// ==UserScript== // @name 微博热点回复 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 微博热点回复 // @match https://*.weibo.com/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_getResourceText // @connect weibo.com // @connect ark.cn-beijing.volces.com // @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js // @resource ENC_KEY ZWNkOTg2OGItMzBjYy00NmExLTg1MWUtODNkZWMzMjBlNmU0 // ==/UserScript== (function () { "use strict"; // 动态获取当前域名 const currentDomain = window.location.hostname; const CONFIG = { commentTemplate: "支持正能量!👍", checkInterval: 300000, // 5分钟检查一次 cooldownPeriod: 900000, // 15分钟冷却时间 maxCommentsPerCycle: 25, // 每个周期最大评论数 } // 将密钥转换为字节数组 function keyToBytes(key) { const bytes = []; for (let i = 0; i < key.length; i += 2) { bytes.push(parseInt(key.substr(i, 2), 16)); } return bytes; } // XOR 加密/解密函数 function xorCrypto(input, keyBytes) { let output = ''; for (let i = 0; i < input.length; i++) { const charCode = input.charCodeAt(i) ^ keyBytes[i % keyBytes.length]; output += String.fromCharCode(charCode); } return output; } // 加密函数 function encrypt(plaintext,SECRET_KEY) { const keyBytes = keyToBytes(SECRET_KEY); return btoa(xorCrypto(plaintext, keyBytes)); // 使用 Base64 编码 } // 解密函数 function decryptToken(ciphertext,SECRET_KEY) { const keyBytes = keyToBytes(SECRET_KEY); const decoded = atob(ciphertext); // 使用 Base64 解码 return xorCrypto(decoded, keyBytes); } // 使用示例 --------------------------------------------------- // 生成密钥(推荐使用安全随机数生成) const secretKey = "666f2fdde94d9f0d1120404a85b1d800494556a7815bef3c526389ea523c45f4"; // CryptoJS.lib.WordArray.random(256/8).toString(); const encryptedToken="A1wd698rqTw8QyUvt5zsYnEge57iOd0RYga60mBfJ5JUWRbq" //"e3266f61-cee2-4b8e-9cb2-0e382cbf2697" // 解密验证 const decryptedToken = decryptToken(encryptedToken, secretKey); // 全局状态 let timer = null; let cooldownTimer = null; let toggleButton = null; let countElement = null; // 初始化入口 function init() { initPanel(); initEventListeners(); updateCounter(); } // 新增冷却状态提示 function showCoolDownTip() { if (!document.getElementById("coolDownTip")) { const tip = document.createElement("div"); tip.id = "coolDownTip"; tip.style = `position: fixed; top: 130px; right: 20px; background: #ff9800; color: white; padding: 8px; border-radius: 4px;`; tip.textContent = "冷却中(15分钟)"; document.body.appendChild(tip); } } // 获取CSRF Token function getXsrfToken() { const match = document.cookie.match(/XSRF-TOKEN=([^;]+)/); return match ? decodeURIComponent(match[1]) : ""; } // 初始化控制面板 function initPanel() { GM_addStyle(` #weibo-comment-panel { position: fixed; top: 100px; right: 20px; background: #fff; padding: 15px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 99999; } #toggleBtn { margin-top: 10px; padding: 5px 15px; cursor: pointer; } `); const panelHTML = `
今日已评论:0/${CONFIG.maxCommentsPerCycle}
`; const panel = document.createElement("div"); panel.id = "weibo-comment-panel"; panel.innerHTML = panelHTML; document.body.appendChild(panel); // 获取元素引用 toggleButton = document.getElementById("toggleBtn"); countElement = document.getElementById("commentCount"); } // 初始化事件监听 function initEventListeners() { if (toggleButton) { toggleButton.addEventListener("click", handleToggle); } else { console.error("无法找到切换按钮"); } } // 主流程控制 async function mainProcess() { try { // const todayCount = GM_getValue('dailyCount', 0); // if (todayCount >= CONFIG.maxCommentsPerDay) { // stopTimer(); // return; // } await processWeibo(); updateCounter(); } catch (e) { console.error("处理失败:", e); } } // 获取微博列表 function fetchWeiboList() { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", //url: `https://${currentDomain}/ajax/feed/unreadfriendstimeline?list_id=100015273983120&refresh=4&since_id=${CONFIG.since_id}&count=15`, url: `https://${currentDomain}/ajax/feed/hottimeline?since_id=0&refresh=0&group_id=102803&containerid=102803&extparam=discover%7Cnew_feed&max_id=0&count=10`, // url:`https://${currentDomain}/ajax/feed/unreadfriendstimeline?list_id=100016096514678&refresh=4&since_id=0&count=15`, headers: { "X-Requested-With": "XMLHttpRequest", Cookie: document.cookie, "X-XSRF-TOKEN": getXsrfToken(), }, onload: (res) => { try { const data = JSON.parse(res.responseText); if (data.ok === 1) { GM_setValue("since_id", data.max_id_str); resolve(data.statuses); } } catch (e) { reject(e); } }, onerror: reject, }); }); } // 发送评论 function postComment(weiboId, content) { return new Promise((resolve, reject) => { console.log("回复的内容:" + content); GM_xmlhttpRequest({ method: "POST", url: `https://${currentDomain}/ajax/comments/create`, headers: { "Content-Type": "application/x-www-form-urlencoded", "X-XSRF-TOKEN": getXsrfToken(), Cookie: document.cookie, }, data: `id=${weiboId}&comment=${encodeURIComponent( content )}&pic_id=&is_repost=0&comment_ori=0&is_comment=0`, onload: resolve, onerror: reject, }); }); } // 修改后的处理微博流程 async function processWeibo() { try { const currentCount = GM_getValue("commentCount", 0); // 达到限制时进入冷却 if (currentCount >= CONFIG.maxCommentsPerCycle) { stopTimer(); GM_setValue("commentCount", 0); showCoolDownTip(); cooldownTimer = setTimeout(() => { document.getElementById("coolDownTip").remove(); startTimer(); }, CONFIG.cooldownPeriod); return; } const weiboList = await fetchWeiboList(); // const targetWeibos = weiboList.filter(weibo => // CONFIG.keywords.some(keyword => // weibo.text_raw.includes(keyword) // ) // ); for (const weibo of weiboList) { if (GM_getValue("commentCount", 0) >= CONFIG.maxCommentsPerCycle) break; await new Promise((r) => setTimeout(r, 2000)); const content = await generateContent(weibo.text_raw); await postComment(weibo.id, content); GM_setValue("commentCount", GM_getValue("commentCount", 0) + 1); updateCounter(); // 实时检查评论限制 if (GM_getValue("commentCount", 0) >= CONFIG.maxCommentsPerCycle) { stopTimer(); showCoolDownTip(); cooldownTimer = setTimeout(() => { document.getElementById("coolDownTip").remove(); GM_setValue("commentCount", 0); startTimer(); }, CONFIG.cooldownPeriod); break; } } } catch (e) { console.error("处理失败:", e); } } // 修改后的定时器控制 function startTimer() { if (!timer) { timer = setInterval(() => { processWeibo().catch(console.error); }, CONFIG.checkInterval); // 立即执行一次检查 processWeibo().catch(console.error); updateButtonState(); } } function stopTimer() { if (timer) { clearInterval(timer); timer = null; updateButtonState(); } if (cooldownTimer) { clearTimeout(cooldownTimer); cooldownTimer = null; } } // 更新状态显示 function updateCounter() { if (countElement) { countElement.textContent = GM_getValue("commentCount", 0); countElement.style.color = GM_getValue("commentCount", 0) >= CONFIG.maxCommentsPerCycle ? "red" : "inherit"; } } // 按钮点击处理(修复版) function handleToggle() { if (timer) { stopTimer(); } else { startTimer(); // 立即执行一次 mainProcess().catch(console.error); } updateButtonState(); } // 更新按钮状态 function updateButtonState() { if (toggleButton) { toggleButton.textContent = timer ? "暂停" : "启动"; toggleButton.style.backgroundColor = timer ? "#ff4444" : "#4CAF50"; } } // 更新计数器 // function updateCounter() { // if (countElement) { // countElement.textContent = GM_getValue('dailyCount', 0); // } // } // 修改后的generateContent函数 function generateContent(content) { console.log("需要回复的内容:" + content); const prompt = `根据以下微博内容生成一句积极温暖的回复(口语化、带表情符号、不超过40字):${content}`; return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: "https://ark.cn-beijing.volces.com/api/v3/chat/completions", headers: { Authorization: `Bearer ${decryptedToken}`, "Content-Type": "application/json", }, data: JSON.stringify({ model: "deepseek-v3-241226", messages: [ { role: "system", content: "你是一个社交媒体回复助手。", }, { role: "user", content: prompt, }, ], max_tokens: 150, }), onload: function (response) { try { const result = JSON.parse(response.responseText); if (result.choices && result.choices[0].message.content) { resolve( result.choices[0].message.content .replace(/【\d+†.*】/g, "") // 清理特殊标记 .trim() ); } else { throw new Error("API返回格式异常"); } } catch (e) { console.error("解析失败:", e); reject(e); } }, onerror: function (err) { console.error("请求失败:", err); reject(err); }, }); }); } // 页面加载初始化 if (document.readyState === "complete") { init(); } else { window.addEventListener("load", init); } })();