// ==UserScript== // @name 知乎批量关注 // @namespace xyz_zyz-%e7%b1%bb%e5%90%8d%e6%88%aa%e5%9b%be%e5%b7%a5%e5%85%b7 // @version 1.0 // @description 完美适配知乎SPA的批量关注+私信脚本 // @author xyz_xyz // @match https://www.zhihu.com/people/*/followers* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @connect zhihu.com // @run-at document-idle // ==/UserScript== (function() { 'use strict'; // 配置参数 const CONFIG = { followDelay: 1000, messageDelay: 1000, messageContent: "互", maxUsers: 20, checkInterval: 1000, maxRetry: 5 }; // 状态管理 const state = { btnAdded: false, processing: false, retryCount: 0 }; // 主入口 function init() { console.log('[知乎助手] 脚本初始化'); setupListeners(); checkAndAddButton(); } // 设置监听器 function setupListeners() { // 监听history变化 const _pushState = history.pushState; history.pushState = function() { _pushState.apply(this, arguments); handleRouteChange(); }; // 监听hash变化 window.addEventListener('hashchange', handleRouteChange); // 轮询检查作为后备方案 setInterval(checkAndAddButton, CONFIG.checkInterval); } // 路由变化处理 function handleRouteChange() { console.log('[知乎助手] 检测到路由变化'); state.btnAdded = false; checkAndAddButton(); } // 检查并添加按钮 function checkAndAddButton() { if (state.btnAdded || state.processing) return; const container = getContentContainer(); if (!container) { if (state.retryCount++ < CONFIG.maxRetry) { console.log('[知乎助手] 等待内容加载...'); } return; } if (shouldAddButton()) { addControlButton(); state.btnAdded = true; state.retryCount = 0; } } // 获取内容容器 function getContentContainer() { return document.querySelector('.Topstory-container') || document.querySelector('.App-main') || document.querySelector('.ContentItem'); } // 判断是否应该添加按钮 function shouldAddButton() { return location.pathname.includes('/people') || document.querySelectorAll('.ContentItem').length > 0; } // 添加控制按钮 function addControlButton() { const existingBtn = document.getElementById('zh-mass-btn'); if (existingBtn) return; const btn = document.createElement('button'); btn.id = 'zh-mass-btn'; btn.className = 'Button Button--blue'; btn.innerHTML = '批量关注+私信'; Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: '2147483647', padding: '8px 16px', borderRadius: '4px', boxShadow: '0 2px 4px rgba(0,0,0,0.2)' }); btn.addEventListener('click', handleMainAction); document.body.appendChild(btn); console.log('[知乎助手] 控制按钮已添加'); } // 主操作处理 function handleMainAction() { if (state.processing) { alert('当前已有操作在进行中'); return; } if (confirm('确定要批量关注这些用户并发送私信吗?')) { state.processing = true; processUsers(); } } // 处理用户列表 function processUsers() { const users = Array.from(document.querySelectorAll('.ContentItem')) .slice(0, CONFIG.maxUsers); if (users.length === 0) { alert('未找到用户列表'); state.processing = false; return; } let processed = 0; users.forEach((user, index) => { setTimeout(() => { processSingleUser(user, index) .then(() => { processed++; if (processed === users.length) { state.processing = false; alert('所有操作已完成'); } }) .catch(err => { console.error('[知乎助手] 处理用户出错:', err); }); }, index * (CONFIG.followDelay + CONFIG.messageDelay)); }); } // 处理单个用户 function processSingleUser(user, index) { return new Promise((resolve) => { // 关注用户 const followBtn = user.querySelector('.FollowButton:not(.Button--grey)'); if (followBtn) { followBtn.click(); console.log(`[知乎助手] 已关注用户 ${index + 1}`); } // 获取用户ID const extraData = user.getAttribute('data-za-extra-module'); if (!extraData) return resolve(); try { const data = JSON.parse(extraData); const memberHashId = data?.card?.content?.member_hash_id; if (!memberHashId) return resolve(); // 发送私信 setTimeout(() => { sendMessage(memberHashId) .then(() => resolve()) .catch(() => resolve()); }, CONFIG.messageDelay); } catch (e) { console.error('[知乎助手] 解析用户数据出错:', e); resolve(); } }); } // 发送私信 function sendMessage(userId) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'POST', url: 'https://www.zhihu.com/api/v4/chat', headers: { 'Content-Type': 'application/json', 'X-Xsrftoken': getCookie('_xsrf') || '' }, data: JSON.stringify({ content_type: 0, receiver_id: userId, text: CONFIG.messageContent }), onload: (res) => { if (res.status >= 200 && res.status < 300) { console.log(`[知乎助手] 私信发送成功: ${userId}`); resolve(); } else { console.error(`[知乎助手] 私信发送失败: ${userId}`, res); reject(); } }, onerror: (err) => { console.error(`[知乎助手] 私信发送错误: ${userId}`, err); reject(); } }); }); } // 获取Cookie function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); return parts.length === 2 ? parts.pop().split(';').shift() : null; } // 启动脚本 if (document.readyState === 'complete') { init(); } else { window.addEventListener('load', init); } })();