您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
2025/9/6 13:12:58
// ==UserScript== // @name 推特 - 翻译机 // @namespace Violentmonkey Scripts // @match *://x.com/* // @version 1.0 // @author - // @description 2025/9/6 13:12:58 // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // ==/UserScript== const max_concurrent = 2; // 并发限制 const queue = []; let cur = 0; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function translation(raw) { return new Promise((resolve) => { const task = async () => { cur++; let attempts = 0; let result; while (attempts < 3) { // 最多重试三次 attempts++; try { result = await big_model(raw); if (!result.error) { break; // 成功,跳出重试 } } catch (e) { // 出现异常也算一次重试 } if (attempts < 3) { await sleep(1000); // 失败后延迟1秒再重试 } } resolve(result); cur--; if (queue.length && cur < max_concurrent) { const next = queue.shift(); next(); } }; if (cur < max_concurrent) { task(); } else { queue.push(task); } }); } function big_model(raw) { return new Promise((resolve) => { GM_xmlhttpRequest({ method: "POST", url: "https://open.bigmodel.cn/api/paas/v4/chat/completions", headers: { "Content-Type": "application/json", "Authorization": "Bearer " + window.big_token }, data: JSON.stringify({ "model": "GLM-4.5-Flash", "temperature": 0, "messages": [ { "role": "system", "content": "翻译为中文,不要解释或包含其他内容" }, { "role": "user", "content": raw } ], "thinking": { "type": "disabled" } }), timeout: 10000, onload: function (response) { try { const data = JSON.parse(response.responseText); if (data.choices?.[0]?.message) { resolve({ "error": false, "msg": data.choices[0].message.content, raw }); } else { resolve({ "error": true, "msg": data, raw }); } } catch (e) { resolve({ "error": true, "msg": e, raw }); } }, onerror: function (err) { resolve({ "error": true, "msg": err, raw }); }, ontimeout: function () { resolve({ "error": true, "msg": "timeout", raw }); } }); }); } function observe() { const observer = new MutationObserver(mutations => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (!(node instanceof HTMLElement)) continue; if (node.matches?.('div[dir="auto"][lang]')) { handle(node); } const descendants = node.querySelectorAll?.('div[dir="auto"][lang]'); if (descendants?.length) { descendants.forEach(handle); } } } }); observer.observe(document.body, { childList: true, subtree: true }); } function handle(e) { if ("raw" in e) return; const text = raw(e); e.raw = text; if (!filter(text) && e.raw) { translation(text).then(r => { if (!r.error || r.error) { const p = document.createElement('p'); p.textContent = "\n\n-----------智谱4.5Flash翻译-----------\n\n\n"; p.style.fontFamily = "'Microsoft YaHei', 微软雅黑, sans-serif"; e.appendChild(p); // 译文 const div = document.createElement('div'); div.textContent = to(r.msg); div.style.fontFamily = "'Microsoft YaHei', 微软雅黑, sans-serif"; e.appendChild(div); } }) } function raw(e) { e.querySelectorAll('img[alt]').forEach(img => { const emoji = img.alt; const textNode = document.createTextNode(emoji); img.replaceWith(textNode); }); return e.textContent; } function filter(text) { const chinese_regex = /[\u4e00-\u9fff]/; const japanese_regex = /[\u3040-\u30ff]/; const contains_chinese = chinese_regex.test(text); const contains_japanese = japanese_regex.test(text); return contains_chinese && !contains_japanese; } function to(value) { if (value === null || value === undefined) { return String(value); } if (typeof value === 'object') { try { return JSON.stringify(value); } catch (e) { return String(value); } } return String(value); } } (function main() { window['big_token'] = GM_getValue("big_token", null) if (big_token == null) { big_token = prompt("请填写智谱Token:") if (big_token.length != 0) { GM_setValue("big_token", big_token) } else { alert("如果没有请禁用,避免无意义弹窗"); } } document.querySelectorAll('div[dir="auto"][lang]').forEach(handle); observe(); })();