Skip to content

Commit

Permalink
Merge pull request #3 from omegaduncan/fix
Browse files Browse the repository at this point in the history
fix: properly await async functions and correct fetch usage
  • Loading branch information
TechDecryptor authored Oct 14, 2024
2 parents e77692f + 0d823a3 commit 492079c
Showing 1 changed file with 134 additions and 61 deletions.
195 changes: 134 additions & 61 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,152 @@
async function translate(text, from, to, options) {
const { utils, detect } = options;
const { tauriFetch: fetch } = utils;
// Papago 翻譯 API 的 URL
const PAPAGO_URL = "https://papago.naver.com/apis/n2mt/translate";

async function getVersion() {
let main_url = "https://papago.naver.com";
let main_re = /\/main.([^"]+)/;
let script_re = /v1.([^"]+)/
let res = await fetch(main_url,{
method: "GET",
reponseType: 2
// 注意:確保 CryptoJS 已正確引入,假設它已在全局範圍內可用
// 如果使用模塊化系統,請使用適當的導入方式
// 例如:const CryptoJS = require("crypto-js");

// 獲取 Papago 版本號
async function getVersion() {
try {
const mainUrl = "https://papago.naver.com";
const mainRe = /\/main\.([^"]+)/;
const scriptRe = /v1\.([^"]+)/;

// 獲取主頁面內容
const res = await fetch(mainUrl, {
method: "GET"
});
if (res.ok){
let html = res.data;
let script_url = `${main_url}${html.match(main_re)[0]}`;
let script_res = await fetch(script_url,{
method: "GET",
reponseType: 2
if (res.ok) {
const html = await res.text();
console.log("Main HTML:", html.substring(0, 200));

// 提取腳本 URL
const scriptUrlMatch = html.match(mainRe);
if (!scriptUrlMatch) {
throw new Error("Failed to find script URL");
}
const scriptUrl = `${mainUrl}${scriptUrlMatch[0]}`;
console.log("Script URL:", scriptUrl);

// 獲取腳本內容
const scriptRes = await fetch(scriptUrl, {
method: "GET"
});
if (script_res.ok) {
let script = script_res.data;
let version = script.match(script_re)[0];
return version;
if (scriptRes.ok) {
const script = await scriptRes.text();
console.log("Script content:", script.substring(0, 200));

// 提取版本號
const versionMatch = script.match(scriptRe);
if (!versionMatch) {
throw new Error("Failed to find version");
}
return versionMatch[0];
}
}
throw new Error("Failed to get version");
} catch (error) {
console.error("Error in getVersion:", error);
throw error;
}
}

// 生成 UUID
function generateUUID() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}

async function getToken() {
let uuid = crypto.randomUUID();
let time = Date.now()
let version = await getVersion();
let key = CryptoJS.enc.Utf8.parse(version);
let data = `${uuid}\n${URL}\n${time}`;
let dataBytes = CryptoJS.enc.Utf8.parse(data);
// 使用 CryptoJS 計算 HMAC-MD5 並轉換為 URL 安全的 Base64
function hmacMD5(key, message) {
const hash = CryptoJS.HmacMD5(CryptoJS.enc.Utf8.parse(message), CryptoJS.enc.Utf8.parse(key));
const base64Hash = CryptoJS.enc.Base64.stringify(hash);
return base64Hash.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

// 獲取認證 Token
async function getToken() {
try {
const uuid = crypto.randomUUID();
const time = Date.now();
const version = await getVersion();
console.log("Version:", version);

// 計算 HMAC
const key = CryptoJS.enc.Utf8.parse(version);
const data = `${uuid}\n${PAPAGO_URL}\n${time}`;
const dataBytes = CryptoJS.enc.Utf8.parse(data);
const hash = CryptoJS.HmacMD5(dataBytes, key);
const base64Hash = CryptoJS.enc.Base64.stringify(hash);

return[base64Hash, uuid, time];
console.log("Generated HMAC:", base64Hash);
return [base64Hash, uuid, time];
} catch (error) {
console.error("Error in getToken:", error);
throw error;
}
let [hash,uuid,time] = getToken();
}

let formData = new FormData();
formData.insert("deviceId", uuid);
formData.insert("locale", to);
formData.insert("dict", "false");
formData.insert("dictDisplay", "30");
formData.insert("honorific", "false");
formData.insert("instant", "false");
formData.insert("paging", "false");
formData.insert("source", from);
formData.insert("target", to);
formData.insert("text", text);
// 執行翻譯
async function translate(text, from, to, options) {
const { utils, detect } = options;
const { tauriFetch: fetch } = utils;

const res = await fetch("https://papago.naver.com/apis/n2mt/translate", {
method: 'POST',
headers: {
"Authorization": `PPG ${uuid}:${hash}`,
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Timestamp": time
},
body: {
type: "Form",
payload: formData
}
});
try {
// 獲取認證信息
const [hash, uuid, time] = await getToken();

if (res.ok) {
let result = res.data;
const { translatedText } = result;
if (translatedText) {
return translatedText;
// 準備請求數據
const formData = {
deviceId: uuid,
locale: to,
dict: "false",
dictDisplay: "30",
honorific: "false",
instant: "false",
paging: "false",
source: from,
target: to,
text: text,
usageAgreed: "false"
};

console.log("Request Body:", formData);

// 發送翻譯請求
const res = await fetch(PAPAGO_URL, {
method: 'POST',
headers: {
"Authorization": `PPG ${uuid}:${hash}`,
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Timestamp": time.toString(),
"Device-Type": "pc",
"X-Apigw-Partnerid": "papago"
},
body: {
type: "Form",
payload: formData
}
});

console.log("Response Status:", res.status);
const responseData = res.data; // Tauri 可能已經解析了 JSON
console.log("Response Data:", responseData);

// 處理響應
if (res.ok) {
const { translatedText } = responseData;
if (translatedText) {
return translatedText;
} else {
throw JSON.stringify(responseData);
}
} else {
throw JSON.stringify(result);
throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(responseData)}`;
}
} else {
throw `Http Request Error\nHttp Status: ${res.status}\n${JSON.stringify(res.data)}`;
} catch (error) {
console.error("Translation error:", error);
throw error;
}
}
}

0 comments on commit 492079c

Please sign in to comment.