koishi-plugin-ll-schedule 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +50 -8
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -32,7 +32,7 @@ exports.usage = `定时发送插件:设置时间自动向指定群发送文字
32
32
  - \`schedule.test <任务名>\`:立即测试发送
33
33
  - \`lls.*\`:以上命令的备用入口(lls.sub / lls.unsub / lls.sublist / lls.list / lls.test)
34
34
 
35
- 订阅/取消订阅的权限等级可在设置页 \`subscribeAuthority\` 调整(默认 2=群管理)。
35
+ 订阅/取消订阅所需权限等级在设置页 \`subscribeAuthority\` 调整(默认 1=所有人都能订阅)。\`subscribeAdminBypass\`(默认开启):群主/群管理可无视权限等级直接订阅——插件从群消息自带的成员角色判断(\`owner\`/\`admin\`),**不需要申请接口权限**。想验证自己角色可发 \`我的ID\`。
36
36
 
37
37
  ## 官机(官方QQ机器人)说明
38
38
 
@@ -65,8 +65,11 @@ const Config = Schema.object({
65
65
  .default('取消订阅')
66
66
  .description('群内取消订阅的关键词(如"取消订阅 任务名")'),
67
67
  subscribeAuthority: Schema.number()
68
- .min(1).max(4).default(2)
69
- .description('订阅/取消订阅所需权限等级(1=所有人 2=群管理 3=群主 4=管理员)'),
68
+ .min(1).max(4).default(1)
69
+ .description('执行订阅命令所需的最低权限等级(Koishi 用户权限等级,与QQ群主/管理员身份无关;默认 1=所有人都能订阅。如需限制,先在控制台"用户管理"给指定账号提权,再调高此值)'),
70
+ subscribeAdminBypass: Schema.boolean()
71
+ .default(true)
72
+ .description('群主/群管理可无视上面的权限等级直接订阅(从消息自带的成员角色判断,无需申请接口权限)'),
70
73
  sendAllWhenEmpty: Schema.boolean()
71
74
  .default(true)
72
75
  .description('任务未指定群也没有群订阅时,发送给该机器人所有已知群'),
@@ -428,6 +431,35 @@ function apply(ctx, config) {
428
431
  })
429
432
 
430
433
  // ===== 群内订阅命令 =====
434
+ // 判断发送者是否群主/群管理:
435
+ // 1) 优先用消息事件自带的成员角色(官机/OneBot 群消息都会带,零 API 调用,不受接口权限限制)
436
+ // 2) 兜底调 getGuildMember(需要接口权限,拿不到就忽略)
437
+ async function isGroupAdmin(session) {
438
+ if (!session.guildId || !session.userId) return false
439
+ const role = session.author?.roles?.[0]?.id || session.event?.member?.roles?.[0]?.id
440
+ if (role) return role === 'owner' || role === 'admin' || role === '1' || role === '2'
441
+ if (session.bot && typeof session.bot.getGuildMember === 'function') {
442
+ try {
443
+ const member = await session.bot.getGuildMember(session.guildId, session.userId)
444
+ const r = member?.roles?.[0]?.id
445
+ return r === 'owner' || r === 'admin' || r === '1' || r === '2'
446
+ }
447
+ catch (e) { /* 无接口权限等,忽略 */ }
448
+ }
449
+ return false
450
+ }
451
+
452
+ async function checkSubscribePerm(session) {
453
+ if (session.user?.authority >= config.subscribeAuthority) return true
454
+ if (config.subscribeAdminBypass) return await isGroupAdmin(session)
455
+ return false
456
+ }
457
+
458
+ function permDeniedHint() {
459
+ return '❌ 权限不足:需要 Koishi 用户权限等级 ≥ ' + config.subscribeAuthority +
460
+ (config.subscribeAdminBypass ? ',或为本群群主/群管理' : '')
461
+ }
462
+
431
463
  // 解析订阅命令的任务名:明确指定 → 用它;不填且只有一个启用任务 → 用它;否则返回提示
432
464
  function resolveSubscribeTaskName(taskName) {
433
465
  const tasks = config.tasks || {}
@@ -472,23 +504,27 @@ function apply(ctx, config) {
472
504
  return `✅ 本群已取消订阅任务 "${name}"`
473
505
  }
474
506
 
475
- ctx.command(config.subscribeKeyword + ' [taskName:text]', '让当前群订阅指定任务的推送', { authority: config.subscribeAuthority })
507
+ ctx.command(config.subscribeKeyword + ' [taskName:text]', '让当前群订阅指定任务的推送')
476
508
  .action(async ({ session }, taskName) => {
509
+ if (!(await checkSubscribePerm(session))) return permDeniedHint()
477
510
  return await subscribeCurrentGroup(session, taskName)
478
511
  })
479
512
 
480
- ctx.command('lls.sub [taskName:text]', '订阅推送(备用入口)', { authority: config.subscribeAuthority })
513
+ ctx.command('lls.sub [taskName:text]', '订阅推送(备用入口)')
481
514
  .action(async ({ session }, taskName) => {
515
+ if (!(await checkSubscribePerm(session))) return permDeniedHint()
482
516
  return await subscribeCurrentGroup(session, taskName)
483
517
  })
484
518
 
485
- ctx.command(config.unsubscribeKeyword + ' [taskName:text]', '让当前群取消订阅指定任务的推送', { authority: config.subscribeAuthority })
519
+ ctx.command(config.unsubscribeKeyword + ' [taskName:text]', '让当前群取消订阅指定任务的推送')
486
520
  .action(async ({ session }, taskName) => {
521
+ if (!(await checkSubscribePerm(session))) return permDeniedHint()
487
522
  return await unsubscribeCurrentGroup(session, taskName)
488
523
  })
489
524
 
490
- ctx.command('lls.unsub [taskName:text]', '取消订阅(备用入口)', { authority: config.subscribeAuthority })
525
+ ctx.command('lls.unsub [taskName:text]', '取消订阅(备用入口)')
491
526
  .action(async ({ session }, taskName) => {
527
+ if (!(await checkSubscribePerm(session))) return permDeniedHint()
492
528
  return await unsubscribeCurrentGroup(session, taskName)
493
529
  })
494
530
 
@@ -526,15 +562,18 @@ function apply(ctx, config) {
526
562
  return '📋 订阅列表:\n' + lines.join('\n')
527
563
  })
528
564
 
529
- ctx.command('我的ID', '查看自己的账号信息(openid/群ID)')
565
+ ctx.command('我的ID', '查看自己的账号信息(openid/群ID/角色)')
530
566
  .action(({ session }) => {
531
567
  logger.info('[schedule] 命令被调用: 我的ID')
568
+ const role = session.author?.roles?.[0]?.id || session.event?.member?.roles?.[0]?.id
569
+ const roleName = role === 'owner' ? '群主' : role === 'admin' ? '群管理' : role === 'member' ? '普通成员' : (role || '未知')
532
570
  const lines = [
533
571
  '👤 我的账号信息:',
534
572
  `平台:${session.platform}`,
535
573
  `用户ID:${session.userId}`,
536
574
  ]
537
575
  if (session.guildId) lines.push(`当前群ID:${session.guildId}`)
576
+ if (session.guildId) lines.push(`本群角色:${roleName}`)
538
577
  if (session.channelId && session.channelId !== session.guildId) lines.push(`频道ID:${session.channelId}`)
539
578
  return lines.join('\n')
540
579
  })
@@ -542,12 +581,15 @@ function apply(ctx, config) {
542
581
  ctx.command('lls.me', '查看自己的账号信息(备用入口)')
543
582
  .action(({ session }) => {
544
583
  logger.info('[schedule] 命令被调用: lls.me')
584
+ const role = session.author?.roles?.[0]?.id || session.event?.member?.roles?.[0]?.id
585
+ const roleName = role === 'owner' ? '群主' : role === 'admin' ? '群管理' : role === 'member' ? '普通成员' : (role || '未知')
545
586
  const lines = [
546
587
  '👤 我的账号信息:',
547
588
  `平台:${session.platform}`,
548
589
  `用户ID:${session.userId}`,
549
590
  ]
550
591
  if (session.guildId) lines.push(`当前群ID:${session.guildId}`)
592
+ if (session.guildId) lines.push(`本群角色:${roleName}`)
551
593
  if (session.channelId && session.channelId !== session.guildId) lines.push(`频道ID:${session.channelId}`)
552
594
  return lines.join('\n')
553
595
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-ll-schedule",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Scheduled message sender with text/image support, works with official QQ bot",
5
5
  "main": "index.js",
6
6
  "files": [