feat: 评论间隔随机化 v1.7.6

- 每条评论之间在设定范围内随机等待(默认1~2分钟,可自定义,支持小数)
- 进度条实时倒计时显示剩余秒数,可随时停止
- 填0则不等待
This commit is contained in:
88531 committed 2026-10-10 15:14:19 +08:00
1 parent 8193e6c0c5
commit 2e97e62210
7 files changed
+179 -8

No files matched your search

+12 -3
View File
@@ -2,7 +2,7 @@
> 一键搜索 · 自动点击 · 智能评论 —— 小红书运营引流的效率神器
[![版本](https://img.shields.io/badge/版本-1.7.5-ff2442.svg)](https://dl.88531.cn/xhs.html)
[![版本](https://img.shields.io/badge/版本-1.7.6-ff2442.svg)](https://dl.88531.cn/xhs.html)
[![平台](https://img.shields.io/badge/平台-Chrome%20%7C%20Edge-4caf50.svg)](#安装方法)
[![语言](https://img.shields.io/badge/语言-纯%20JavaScript-2196f3.svg)](#开发说明)
@@ -74,6 +74,12 @@
未配置对应内容时(如选了文字模式但库是空的),选项下方会给出橙色提示。
### ⏱️ 评论间隔(防风控)
- 每条评论之间随机等待设定范围(默认 1~2 分钟,可改为任意范围,支持小数)
- 例如填 1 和 2:每篇笔记评论完后随机等 60~120 秒再处理下一篇
- 填 0 和 0 则不等待(不推荐)
- 等待期间进度条实时倒计时,点「⏹️ 停止」随时中断
### 手动触发 / 元素检测
- 在小红书页面点「🤖 自动点击笔记」立即开始;点「🧪 测试元素检测」排查页面识别问题
@@ -101,10 +107,13 @@
## 📜 版本历史
当前版本:**1.7.5**
当前版本:**1.7.6**
<details>
<summary>展开查看完整变更记录(v1.2.0 ~ v1.7.5)</summary>
<summary>展开查看完整变更记录(v1.2.0 ~ v1.7.6)</summary>
### 1.7.6
- **评论间隔随机化**:每条评论之间在设定范围内随机等待(默认 1~2 分钟,可自定义),进度条实时倒计时,模拟真人浏览节奏更安全
### 1.7.5
- 试用倒计时精确到秒(HH:MM:SS 每秒刷新,归零自动锁定)
+1 -1
View File
@@ -16,7 +16,7 @@ const DEFAULT_AI = {
const AUTH_BASE = 'https://auth.88531.cn';
const AUTH_PROJECT_ID = 3;
const AUTH_API_KEY = 'ak_bbf83b76df8219388d7f60b9e67c7db2';
const CLIENT_VERSION = '1.7.5';
const CLIENT_VERSION = '1.7.6';
const TRIAL_MS = 24 * 60 * 60 * 1000; // 未授权试用1天
// 把用户填写的地址规范化为完整的 chat/completions 端点
+48 -2
View File
@@ -896,8 +896,8 @@ class XHSNoteSaver {
console.log(`已点击第 ${totalClicked} 个笔记`);
// 等待内容展开,增加等待时间
await this.sleep(2000);
// 评论间隔:在设定范围内随机等待(如1~2分钟),模拟真人节奏
await this.randomCommentDelay();
} catch (error) {
console.error('点击笔记失败:', error);
@@ -1501,6 +1501,52 @@ class XHSNoteSaver {
});
}
// 评论间隔:最小~最大分钟之间随机等待,进度条实时倒计时
async randomCommentDelay() {
let min = 1;
let max = 2;
try {
const result = await chrome.storage.local.get(['commentDelayMin', 'commentDelayMax']);
const parsedMin = Number(result.commentDelayMin);
const parsedMax = Number(result.commentDelayMax);
if (Number.isFinite(parsedMin) && parsedMin >= 0) min = parsedMin;
if (Number.isFinite(parsedMax) && parsedMax >= 0) max = parsedMax;
} catch (error) {
console.log('读取评论间隔失败,使用默认 1~2 分钟:', error);
}
if (max < min) [min, max] = [max, min];
// 都是0则不等待
if (min === 0 && max === 0) return;
const totalSec = Math.round((min + Math.random() * (max - min)) * 60);
console.log(`评论间隔:随机等待 ${totalSec} 秒(范围 ${min}~${max} 分钟)`);
// 进度条提示实时倒计时
const tip = document.querySelector('.xhs-progress-tip');
let remain = totalSec;
const renderTip = () => {
if (tip) {
tip.textContent = remain > 0
? `⏳ 评论间隔:随机等待 ${remain} 秒后继续下一篇…`
: '💡 长按评论模式按钮可管理自定义评论';
}
};
renderTip();
const countdownTimer = setInterval(() => {
remain--;
renderTip();
}, 1000);
this.cleanupTimers.add(countdownTimer);
await this.sleep(totalSec * 1000);
clearInterval(countdownTimer);
this.cleanupTimers.delete(countdownTimer);
renderTip();
}
// 阻止笔记元素内的所有链接跳转
preventLinkNavigation(noteElement) {
const links = noteElement.querySelectorAll('a');
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "小红书自动评论助手",
"version": "1.7.5",
"version": "1.7.6",
"description": "右侧侧边栏常驻的自动评论助手,支持试用/卡密授权、固定池/自定义文字/图片/AI评论",
"permissions": [
"storage",
+57
View File
@@ -220,6 +220,63 @@ body {
line-height: 1.4;
}
/* 评论间隔配置 */
.delay-config {
margin-top: 12px;
padding: 12px;
background: #f8f9fa;
border-radius: 6px;
border: 1px solid #e9ecef;
}
.delay-label {
display: block;
font-size: 13px;
font-weight: 500;
color: #333;
margin-bottom: 8px;
}
.delay-inputs {
display: flex;
align-items: center;
gap: 8px;
}
.delay-input {
flex: 1;
min-width: 0;
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 13px;
outline: none;
text-align: center;
}
.delay-input:focus {
border-color: #4caf50;
}
.delay-sep {
color: #999;
font-size: 13px;
}
.delay-unit {
font-size: 12px;
color: #666;
white-space: nowrap;
}
.delay-config small {
display: block;
margin-top: 6px;
color: #666;
font-size: 11px;
line-height: 1.4;
}
.mode-selector {
margin-top: 12px;
padding: 12px;
+11 -1
View File
@@ -84,6 +84,16 @@
</label>
<small>勾选后会在点击笔记时展开内容,取消勾选则只简单点击</small>
</div>
<div class="delay-config">
<label class="delay-label">⏱️ 评论间隔(每条评论之间随机等待)</label>
<div class="delay-inputs">
<input type="number" id="delay-min" class="delay-input" min="0" step="0.1" placeholder="最小 1">
<span class="delay-sep">~</span>
<input type="number" id="delay-max" class="delay-input" min="0" step="0.1" placeholder="最大 2">
<span class="delay-unit">分钟</span>
</div>
<small>在最小~最大之间随机取值,模拟真人节奏(如填 1 和 2 = 每篇随机等 1~2 分钟);填 0 则不等待</small>
</div>
<div class="mode-selector">
<div class="mode-label">评论方式</div>
<div class="mode-options">
@@ -201,7 +211,7 @@
<div class="footer">
<div class="version-info">
<span>版本: 1.7.5</span>
<span>版本: 1.7.6</span>
<span>侧边栏常驻 · 专注于自动评论</span>
</div>
</div>
+49
View File
@@ -12,6 +12,7 @@ class AutoCommentManager {
async init() {
await this.loadClickMode(); // 加载点击模式设置
await this.loadDelayConfig(); // 加载评论间隔设置
await this.loadRegion(); // 加载按地区搜索设置
await this.loadApiKey(); // 加载API密钥
await this.loadModelConfig(); // 加载自定义模型配置
@@ -79,6 +80,16 @@ class AutoCommentManager {
this.saveClickMode(e.target.checked);
});
// 评论间隔:输入即保存
['delay-min', 'delay-max'].forEach((id) => {
const input = document.getElementById(id);
if (input) {
input.addEventListener('input', () => {
this.saveDelayConfig();
});
}
});
// 评论方式选择(固定评论池 / 自定义文字 / 图片 / AI 按笔记生成)
document.querySelectorAll('input[name="comment-mode"]').forEach((radio) => {
radio.addEventListener('change', (e) => {
@@ -466,6 +477,44 @@ class AutoCommentManager {
}
}
// 加载评论间隔(分钟,默认 1~2 分钟随机)
async loadDelayConfig() {
try {
const result = await chrome.storage.local.get(['commentDelayMin', 'commentDelayMax']);
const min = Number(result.commentDelayMin);
const max = Number(result.commentDelayMax);
const minInput = document.getElementById('delay-min');
const maxInput = document.getElementById('delay-max');
if (minInput) minInput.value = Number.isFinite(min) && min >= 0 ? min : 1;
if (maxInput) maxInput.value = Number.isFinite(max) && max >= 0 ? max : 2;
console.log('加载评论间隔:', minInput?.value, '~', maxInput?.value, '分钟');
} catch (error) {
console.error('加载评论间隔失败:', error);
}
}
// 保存评论间隔
async saveDelayConfig() {
try {
const minInput = document.getElementById('delay-min');
const maxInput = document.getElementById('delay-max');
let min = Number(minInput?.value);
let max = Number(maxInput?.value);
if (!Number.isFinite(min) || min < 0) min = 1;
if (!Number.isFinite(max) || max < 0) max = 2;
if (max < min) {
// 自动纠正顺序
[min, max] = [max, min];
if (minInput) minInput.value = min;
if (maxInput) maxInput.value = max;
}
await chrome.storage.local.set({ commentDelayMin: min, commentDelayMax: max });
console.log('保存评论间隔:', min, '~', max, '分钟');
} catch (error) {
console.error('保存评论间隔失败:', error);
}
}
// 保存API密钥
async saveApiKey(apiKey) {
try {