fix: detect fake imtype for qdreader cron

This commit is contained in:
2026-05-23 13:22:26 +08:00
parent 8d59be2d71
commit 7388cf8eb5
4 changed files with 42 additions and 26 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ Python 示例:
- `rule` 支持正则,可写多行表示多个触发规则。
- `cron` 支持 5 位或 6 位 cron 表达式。
- 定时入口必须按运行环境判断,而不是只靠“消息内容为空”。推荐先检测 `ImType()` / `GetImType()` 是否为 `cron`,命中后直接走定时分支;不要在主入口用 `input()` 兜底读取命令内容。`input()` 是交互等待函数,定时场景可能返回 `q`、阻塞或把空触发误判成普通命令,导致 cron 已触发但业务没跑。参考茅台插件模式:`ImType() === "cron" ? "fake" : ImType()` 后显式进入 `cronTask()`
- 定时入口必须按运行环境判断,而不是只靠“消息内容为空”。推荐先检测 `ImType()` / `GetImType()` 是否为 `cron` / `task` / `fake`,命中后直接走定时分支;BOSS 实测 Autman cron 触发时日志上下文为 `content: ""``ImType/GetImType: "fake"`不要在主入口用 `input()` 兜底读取命令内容。`input()` 是交互等待函数,定时场景可能返回 `q`、阻塞或把空触发误判成普通命令,导致 cron 已触发但业务没跑。参考茅台插件模式:`ImType() === "cron" ? "fake" : ImType()` 后显式进入 `cronTask()`
- cron 头注兼容性优先使用带空格格式 `// [cron: 1 7 * * *]`,避免不同 Autman 解析器只识别一种注释风格。
- `admin: true` 表示仅管理员可执行。
- `priority` 数字越大优先级越高。
+12 -5
View File
@@ -4,7 +4,7 @@
//[author: Hermes]
//[service: BOSS]
//[class: 工具类]
// [version: 2.15.1]
// [version: 2.15.2]
// [platform: web,qq,wx,tg,tb,fs,we]
// [public: false]
// [price: 0]
@@ -264,12 +264,19 @@ function maskUid(uid) {
return uid.slice(0, 2) + "***" + uid.slice(-2)
}
function contentText() {
var s = ""
function runtimeImType() {
var im = ""
try { if (typeof ImType === "function") im = ImType() || "" } catch (e) {}
try { if (!im && typeof GetImType === "function") im = GetImType() || "" } catch (e2) {}
if (lower(trim(im)) === "cron") return ""
return lower(trim(im))
}
function isSchedulerImType(im) {
im = lower(trim(im))
return im === "cron" || im === "task" || im === "fake"
}
function contentText() {
var s = ""
if (isSchedulerImType(runtimeImType())) return ""
try { if (typeof getContent === "function") s = getContent() || "" } catch (e3) {}
try { if (!s && typeof GetContent === "function") s = GetContent() || "" } catch (e4) {}
try { if (!s && typeof sender !== "undefined" && sender && sender.getContent) s = sender.getContent() || "" } catch (e5) {}
@@ -279,7 +286,7 @@ function contentText() {
}
function usage() {
return [
"启点读书签到插件 v2.15.1",
"启点读书签到插件 v2.15.2",
"【一级菜单】",
"账号管理:启点账号",
"执行查询:启点查询",
+12 -5
View File
@@ -4,7 +4,7 @@
//[author: Hermes]
//[service: BOSS]
//[class: 工具类]
// [version: 2.15.1]
// [version: 2.15.2]
// [platform: web,qq,wx,tg,tb,fs,we]
// [public: false]
// [price: 0]
@@ -264,12 +264,19 @@ function maskUid(uid) {
return uid.slice(0, 2) + "***" + uid.slice(-2)
}
function contentText() {
var s = ""
function runtimeImType() {
var im = ""
try { if (typeof ImType === "function") im = ImType() || "" } catch (e) {}
try { if (!im && typeof GetImType === "function") im = GetImType() || "" } catch (e2) {}
if (lower(trim(im)) === "cron") return ""
return lower(trim(im))
}
function isSchedulerImType(im) {
im = lower(trim(im))
return im === "cron" || im === "task" || im === "fake"
}
function contentText() {
var s = ""
if (isSchedulerImType(runtimeImType())) return ""
try { if (typeof getContent === "function") s = getContent() || "" } catch (e3) {}
try { if (!s && typeof GetContent === "function") s = GetContent() || "" } catch (e4) {}
try { if (!s && typeof sender !== "undefined" && sender && sender.getContent) s = sender.getContent() || "" } catch (e5) {}
@@ -279,7 +286,7 @@ function contentText() {
}
function usage() {
return [
"启点读书签到插件 v2.15.1",
"启点读书签到插件 v2.15.2",
"【一级菜单】",
"账号管理:启点账号",
"执行查询:启点查询",
+10 -8
View File
@@ -752,25 +752,27 @@ test('manual sign replies per account first and summary separately for multi-acc
assert.match(r.replies[2], /日志已归档/);
});
test('cron detection uses ImType cron and does not consume input as command text', () => {
test('cron detection uses ImType cron/fake and does not consume input as command text', () => {
const store = {
qdreader_cookie_json: JSON.stringify({ '12345': cookie }),
qdreader_user_bind_json: JSON.stringify({ '12345': 'user-a' }),
};
for (const imType of ['cron', 'fake']) {
const r = runPlugin({
content: '',
store,
content: imType === 'fake' ? 'q' : '',
store: { ...store },
userId: 'cron',
globals: {
ImType: () => 'cron',
ImType: () => imType,
input: () => 'q',
Date: fixedDateClass('2026-05-19T07:01:00.000+08:00'),
},
});
assert.equal(r.calls.length, 4);
assert.equal(r.replies.length, 1);
assert.match(r.replies[0], /汇总:成功 1 \/ 失败 0 \/ 总计 1/);
assert.match(r.replies[0], /定时任务\/零点任务/);
assert.equal(r.calls.length, 4, imType);
assert.equal(r.replies.length, 1, imType);
assert.match(r.replies[0], /汇总:成功 1 \/ 失败 0 \/ 总计 1/, imType);
assert.match(r.replies[0], /定时任务\/零点任务/, imType);
}
});
test('manual sign only runs current user accounts while cron runs all accounts', () => {