v1.8.0: 新增「发送内容」三选一(只发评论/只发私信不发评论/评论+私信),私信对象明确仅评论区用户;只发私信模式下按增量判断是否记为已处理

This commit is contained in:
personal82555 committed 2026-10-13 22:25:43 +08:00
1 parent 91c4666998
commit a320658ac8
4 files changed
+50 -24

No files matched your search

+27 -11
View File
@@ -960,25 +960,41 @@
step("[" + (task.index + 1) + "/" + task.queue.length + "] " + video.title.slice(0, 30));
const text = video.text || pickTemplate(video.title, cfg.keyword);
const SRC_LABEL = { custom: "自定义", ai: "AI", tpl: "模板" };
step("评论[" + (SRC_LABEL[video.src] || "模板") + "]:" + text.slice(0, 30) + (text.length > 30 ? "…" : ""));
// 发送内容三选一:comment=只评论 / dm=只发私信不发评论 / both=评论+私信
const what = ["comment", "dm", "both"].indexOf(cfg.sendWhat) >= 0 ? cfg.sendWhat : "comment";
const doComment = (what === "comment" || what === "both");
const doDm = (what === "dm" || what === "both");
const r = await sendOne(video, text, cfg.sendMode !== "api");
if (r.stopped) { finish(task, false, "已手动停止"); return; }
if (r.fatal) { finish(task, false, r.fatal); return; }
if (doComment) {
step("评论[" + (SRC_LABEL[video.src] || "模板") + "]:" + text.slice(0, 30) + (text.length > 30 ? "…" : ""));
if (r.ok) {
step(r.verified ? "✅ 评论成功" : "⚠️ 已发送但未在页面确认,记为已评论", r.verified ? "ok" : "fail");
await recordOne(task, video, text, true);
const r = await sendOne(video, text, cfg.sendMode !== "api");
if (r.stopped) { finish(task, false, "已手动停止"); return; }
if (r.fatal) { finish(task, false, r.fatal); return; }
if (r.ok) {
step(r.verified ? "✅ 评论成功" : "⚠️ 已发送但未在页面确认,记为已评论", r.verified ? "ok" : "fail");
await recordOne(task, video, text, true);
} else {
step("❌ 失败:" + r.error, "fail");
await recordOne(task, video, text, false);
}
} else {
step("❌ 失败:" + r.error, "fail");
await recordOne(task, video, text, false);
step("本条不发评论(发送内容=只发私信)");
}
// 私信(可选,评论后对本视频评论区用户发送;风控更严,间隔更长)
if (cfg.dmEnabled && !stopRequested()) {
// 私信:对本视频评论区里发过评论的人发送;风控更严,间隔更长
let dmBefore = task.dmSent || 0; // 本视频发送前的累计数,用于算增量
if (doDm && !stopRequested()) {
await runDmStep(task, video);
}
// 只发私信模式下也要记为「已处理」,否则下次会重复进同一视频
// 注意按「本视频的增量」判断,不能用累计数(否则前面发过就会误记后面没发的)
if (!doComment && (task.dmSent || 0) > dmBefore) {
await recordOne(task, video, text, true);
}
task.index += 1;
if (task.index < task.queue.length && !stopRequested()) {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "B站评论助手",
"version": "1.7.1",
"version": "1.8.0",
"description": "B站网页版关键词评论助手:按搜索关键词找视频,默认模拟真人(打开视频页、滚到评论区、逐字输入、点发布),也可快速API直发;支持下载当前页视频;带防重复记录、可中断执行与页面实时进度浮层。",
"permissions": ["storage", "tabs", "scripting", "sidePanel", "downloads", "declarativeNetRequest"],
"host_permissions": [
+14 -5
View File
@@ -237,11 +237,20 @@
<input type="number" id="minPlay" value="0" min="0">
<span class="unit">次(0 = 不过滤)</span>
</div>
<div id="dmBox" style="margin-top:10px;padding:9px 10px;border:1px dashed #d0a0a0;border-radius:8px;background:#fdf7f7">
<label style="display:flex;align-items:center;gap:6px;font-size:13px;font-weight:bold;color:#c0392b;cursor:pointer">
<input type="checkbox" id="dmEnabled"> ✉ 私信评论区用户(高风险,默认关闭)
</label>
<div id="dmDetail" style="display:none;margin-top:7px">
<div class="row" style="margin-top:8px">
<span class="unit">发送内容</span>
<select id="sendWhat" style="flex:1">
<option value="comment" selected>只发评论(默认)</option>
<option value="dm">只发私信,不发评论</option>
<option value="both">评论 + 私信</option>
</select>
</div>
<div id="dmBox" style="margin-top:8px;padding:9px 10px;border:1px dashed #d0a0a0;border-radius:8px;background:#fdf7f7;display:none">
<div style="font-size:12px;color:#7a5c00;background:#fff8e1;border:1px solid #ffe082;border-radius:4px;padding:5px 8px;line-height:1.55">
私信对象:<b>仅本视频评论区里发过评论的人</b>(不含UP主、不含没评论的路人)。<br>
同一用户<b>终身只发一条</b>,已发过的自动跳过。
</div>
<div style="margin-top:7px">
<div class="row">
<span class="unit">每个视频最多</span>
<select id="dmCount">
+8 -7
View File
@@ -14,11 +14,11 @@
dlQuality: "80",
maxN: 3,
minPlay: 0,
dmEnabled: false,
sendWhat: "comment",
dmCount: 2,
dmText: ""
};
const FIELDS = ["baseUrl", "apiKey", "model", "keyword", "order", "mode", "customText", "sendMode", "tid", "region", "dlQuality", "maxN", "minPlay", "dmEnabled", "dmCount", "dmText"];
const FIELDS = ["baseUrl", "apiKey", "model", "keyword", "order", "mode", "customText", "sendMode", "tid", "region", "dlQuality", "maxN", "minPlay", "sendWhat", "dmCount", "dmText"];
let settings = Object.assign({}, DEFAULTS);
let running = false;
@@ -73,9 +73,10 @@
}
function refreshDmVisibility() {
const cb = $("dmEnabled"), det = $("dmDetail");
if (!cb || !det) return;
det.style.display = cb.checked ? "block" : "none";
const sel = $("sendWhat"), box = $("dmBox");
if (!sel || !box) return;
// 选了「只发私信」或「评论+私信」才展开私信设置区
box.style.display = (sel.value === "dm" || sel.value === "both") ? "block" : "none";
}
function refreshCustomVisibility() {
@@ -339,7 +340,7 @@ function refreshCustomVisibility() {
keyword: kw,
maxN: Number(settings.maxN) || 3,
minPlay: Number(settings.minPlay) || 0,
dmEnabled: settings.dmEnabled === true || settings.dmEnabled === "true",
sendWhat: ["comment", "dm", "both"].indexOf(settings.sendWhat) >= 0 ? settings.sendWhat : "comment",
dmCount: Math.max(1, Math.min(5, Number(settings.dmCount) || 2)),
dmText: String(settings.dmText || "").trim()
}) });
@@ -583,7 +584,7 @@ function refreshCustomVisibility() {
: (el.type === "number") ? (Number(el.value) || 0) : el.value;
saveField(k, v);
if (k === "mode") refreshCustomVisibility();
if (k === "dmEnabled") refreshDmVisibility();
if (k === "sendWhat") refreshDmVisibility();
if (k === "mode" || k === "apiKey" || k === "baseUrl" || k === "model" || k === "customText") refreshModeWarn();
});
if (el.tagName === "TEXTAREA" || el.type === "text" || el.type === "password") {