// ==UserScript== // @name Weibo Comment and Like // @namespace http://tampermonkey.net/ // @version 0.4 // @description [优化版]智能生成多样化评论并点赞 // @author You // @match *://*.weibo.com/* // @grant GM_addStyle // @grant GM_xmlhttpRequest // @grant GM_notification // @grant GM_setValue // @grant GM_getValue // @connect api.siliconflow.cn // @require https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js // ==/UserScript== (function () { 'use strict'; // 缓存配置(新增) const cacheConfig = { CACHE_PREFIX: 'WEIBO_COMMENT_CACHE_', EXPIRE_HOURS: 24 // 缓存有效期24小时 }; GM_addStyle(` .lyric-bubble { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); opacity: 0; background: rgba(0,0,0,0.8); color: #fff; padding: 12px 24px; border-radius: 25px; font-size: 16px; white-space: nowrap; z-index: 99999; box-shadow: 0 4px 12px rgba(0,0,0,0.2); animation: lyricShow 3s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; } @keyframes lyricShow { 0% { opacity: 0; transform: translate(-50%, 100%); } 20% { opacity: 1; transform: translate(-50%, 0); } 80% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; transform: translate(-50%, -100%); } } `); // 移除原来的config.targetWeibo和weiboId const config = { maxCycles: 19, commentInterval: 2500, cooldownDuration: 60000, deepseekToken: "sk-oqwogagrgsaimscnmjitdnhcruyftjsaqsbjsvppsfrberps" }; // 增强缓存模块(新增) const commentCache = { getCacheKey(weiboId) { return `${cacheConfig.CACHE_PREFIX}${weiboId}`; }, get(weiboId) { const cacheData = GM_getValue(this.getCacheKey(weiboId)); if (!cacheData) return null; // 检查缓存时效 const ageHours = (Date.now() - cacheData.timestamp) / (1000 * 60 * 60); return ageHours < cacheConfig.EXPIRE_HOURS ? cacheData.comments : null; }, set(weiboId, comments) { GM_setValue(this.getCacheKey(weiboId), { timestamp: Date.now(), comments: comments }); } }; // 动态获取当前域名 const currentDomain = window.location.hostname; // 增强认证模块 const auth = { // 新增meta标签提取逻辑 getMetaToken() { const meta = document.querySelector('meta[name="csrf-token"]'); return meta ? meta.content : null; }, // 兼容多域名Cookie名称差异 getCookie(name) { const cookies = document.cookie.split(';'); for (let c of cookies) { const [key, val] = c.trim().split('='); if (key === name) return decodeURIComponent(val); } return null; }, get csrfToken() { // 优先级:meta标签 > 各域名专用Cookie > 默认Cookie return this.getMetaToken() || this.getCookie('XSRF-TOKEN') || this.getCookie('_WEIBO_CSRF_TOKEN') || this.getCookie('WB_CSRF'); }, buildHeaders(contentType = 'application/x-www-form-urlencoded') { const headers = { 'Cookie': document.cookie, 'Referer': location.href, 'Content-Type': contentType }; // 仅在存在时添加CSRF头 if (this.csrfToken) { headers['X-XSRF-TOKEN'] = this.csrfToken; headers['X-CSRF-TOKEN'] = this.csrfToken; // 双保险 } return headers; } }; // 修改后的智能回复生成模块 const contentGenerator = { async generate(weiboId, weiboText) { // 先尝试读取缓存 const cached = commentCache.get(weiboId); if (cached) { console.log('从缓存加载评论', weiboId); return cached; } // 缓存未命中则生成新评论 const prompt = `请基于以下微博内容生成20条不同的正能量评论,要求: 1. 每条不超过15字 2. 使用口语化表达 3. 包含内容相关emoji 4. 不要重复句式 微博内容:"${weiboText}" 输出格式:直接返回用中文顿号分隔的评论,不要编号`; try { const response = await fetch('https://api.siliconflow.cn/v1/chat/completions', { method: 'POST', headers: { 'Authorization': `Bearer ${config.deepseekToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ model: "deepseek-ai/DeepSeek-V3", messages: [{ role: "user", content: prompt }], temperature: 0.7, max_tokens: 200 }) }); const data = await response.json(); const comments = data.choices[0].message.content.split('、').filter(Boolean); // 写入缓存 commentCache.set(weiboId, comments); return comments; } catch (error) { console.error('生成失败:', error); return []; } } }; // 新增API模块(关键修复) const weiboAPI = { comment(weiboId, text, callback) { const formData = new URLSearchParams(); formData.append('id', weiboId); formData.append('comment', text); formData.append('is_repost', 0); formData.append('comment_ori', 0); formData.append('is_comment', 0); formData.append('mark', 'followtopweibo'); formData.append('rid', '0_0_50_165173378373554136_0_0_0'); GM_xmlhttpRequest({ method: "POST", url: `https://${currentDomain}/ajax/comments/create`, headers: auth.buildHeaders(), data: formData, onload: function (response) { try { const data = JSON.parse(response.responseText); data.ok === 1 ? callback(data.data?.mid) : console.error("评论失败:", data); } catch (e) { console.error("响应解析失败:", e); } }, onerror: (err) => console.error("请求失败:", err) }); }, like(mid, callback) { GM_xmlhttpRequest({ method: "POST", url: `https://${currentDomain}/ajax/statuses/updateLike`, headers: auth.buildHeaders('application/json'), data: JSON.stringify({ object_id: mid, object_type: "comment" }), onload: function (response) { try { const data = JSON.parse(response.responseText); data.ok === 1 ? callback(true) : console.error("点赞失败:", data); } catch (e) { console.error("响应解析失败:", e); } }, onerror: (err) => console.error("请求失败:", err) }); } }; // 新增微博列表模块 // 修改后的微博列表模块 const weiboList = { // getCurrentUid() { // // 方式1:从页面元素获取 // const uidLink = document.querySelector('a[href*="//weibo.com/u/"]'); // if (uidLink) { // const matches = uidLink.href.match(/\/u\/(\d+)/); // return matches ? matches[1] : null; // } // // 方式2:从当前URL路径获取(兼容新版/旧版微博) // const pathUid = window.location.pathname.match(/\/(u|n)\/(\d+)/); // return pathUid ? pathUid[2] : null; // }, async getUID() { // 方法1:精准提取URL路径中的screen_name const pathname = decodeURIComponent(window.location.pathname); // 解码中文 const screenNameMatch = pathname.match(/^\/(n|u)\/([^\/]+)/); // 匹配 /n/ 或 /u/ 后的非斜杠内容 if (!screenNameMatch || !screenNameMatch[2]) { GM_notification('路径格式异常,请确保在用户主页使用'); return null; } // 方法3:通过API获取 uid try { const response = await fetch(`https://${currentDomain}/ajax/profile/info?screen_name=${encodeURIComponent(screenNameMatch[2])}`); const data = await response.json(); console.log('API响应数据:', data); // 调试输出 if (data?.data?.user?.idstr) { return data.data.user.idstr; } else { GM_notification(`UID获取失败:${data?.msg || '未知错误'}`); return null; } } catch (e) { console.error('API请求失败:', e); GM_notification('网络请求异常,请检查控制台'); return null; } }, async fetchWeiboList() { const uid = await this.getUID(); if (!uid) return []; return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: `https://${currentDomain}/ajax/statuses/mymblog?uid=${uid}&page=1&feature=0`, headers: auth.buildHeaders(), onload: function (response) { try { const data = JSON.parse(response.responseText); const rawList = data.data.list.slice(0, 5) .map(item => ({ id: item.id.toString(), text_raw: item.text_raw, created_at: item.created_at })) .filter(item => item.id && item.text_raw); // 过滤无效数据 resolve(rawList); } catch (e) { reject('解析微博列表失败'); } }, onerror: () => reject('获取微博列表失败') }); }); }, createSelectionUI(list) { const container = document.createElement('div'); container.style.cssText = ` position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px; border-radius: 10px; box-shadow: 0 0 15px rgba(0,0,0,0.2); z-index: 999999; min-width: 400px; `; const title = document.createElement('h3'); title.textContent = '请选择要操作的微博:'; title.style.marginBottom = '15px'; container.appendChild(title); list.forEach(weibo => { const btn = document.createElement('button'); btn.style.cssText = ` display: block; width: 100%; margin: 10px 0; padding: 12px; background: #1890ff; color: white; border: none; border-radius: 5px; cursor: pointer; transition: all 0.2s; `; btn.innerHTML = `