koishi-plugin-ll-schedule 1.7.6 → 1.7.7
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.
- package/index.js +19 -87
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -11,16 +11,15 @@ const { Schema, h } = require('koishi')
|
|
|
11
11
|
|
|
12
12
|
exports.name = 'll-schedule'
|
|
13
13
|
|
|
14
|
-
exports.usage = `剑灵活动提醒:全部活动写在 activities
|
|
14
|
+
exports.usage = `剑灵活动提醒:全部活动写在 activities 活动表里,群里发「剑灵提醒订阅」即可收到所有活动的提前提醒。
|
|
15
15
|
|
|
16
16
|
活动表格式(一份表管所有活动):
|
|
17
17
|
[世界BOSS] 提前:5分钟
|
|
18
18
|
周一 21:00-22:00 地点:白青山脉 / 仙幻岛
|
|
19
19
|
[寻宝] 提前:2分钟
|
|
20
|
-
每天 13:00-
|
|
20
|
+
每天 13:00-15:00
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
管理员:schedule.unsuball(取消所有群的订阅)
|
|
22
|
+
群命令:剑灵提醒订阅 / 取消剑灵订阅 / 订阅列表 / schedule.list / schedule.test / schedule.debug
|
|
24
23
|
`
|
|
25
24
|
|
|
26
25
|
// ===== 纯函数(可单测) =====
|
|
@@ -407,10 +406,7 @@ const Config = Schema.object({
|
|
|
407
406
|
.description('活动提醒是否用 QQ官方 Markdown 卡片发送(仅官机生效,失败自动回退纯文本)'),
|
|
408
407
|
globalGroups: Schema.array(Schema.string())
|
|
409
408
|
.default([])
|
|
410
|
-
.description('额外固定推送群(可选):这些群无需订阅也会收到活动提醒(留空即可,一般用群内"
|
|
411
|
-
unsubAllNotice: Schema.string()
|
|
412
|
-
.default('本群已取消剑灵提醒推送')
|
|
413
|
-
.description('管理员用 schedule.unsuball 取消全部订阅时,发到每个被取消群的提示语(留空则不发送提示)'),
|
|
409
|
+
.description('额外固定推送群(可选):这些群无需订阅也会收到活动提醒(留空即可,一般用群内"剑灵提醒订阅"命令)'),
|
|
414
410
|
permDeniedHint: Schema.string()
|
|
415
411
|
.default('❌ 权限不足,请联系李浅浅,或成为群主/管理员')
|
|
416
412
|
.description('权限不足时的提示语(管理命令/订阅命令都会用它;可改成你自己的联系方式)'),
|
|
@@ -723,7 +719,7 @@ function apply(ctx, config) {
|
|
|
723
719
|
const target = String(rawTarget).trim()
|
|
724
720
|
if (!target) continue
|
|
725
721
|
if (bot.platform === 'qq' && /^\d+$/.test(target)) {
|
|
726
|
-
logger.warn(`[schedule] 任务 "${name}":官方QQ机器人不能用数字群号 "${target}" 发送,请用群内"
|
|
722
|
+
logger.warn(`[schedule] 任务 "${name}":官方QQ机器人不能用数字群号 "${target}" 发送,请用群内"剑灵提醒订阅"命令或 schedule.groups 查看 openid`)
|
|
727
723
|
continue
|
|
728
724
|
}
|
|
729
725
|
try {
|
|
@@ -937,8 +933,8 @@ function apply(ctx, config) {
|
|
|
937
933
|
.action(() => {
|
|
938
934
|
logger.info('[schedule] 命令被调用: schedule')
|
|
939
935
|
return '⚙️ 活动表在插件设置页的 activities 里配置\n' +
|
|
940
|
-
'群内发"
|
|
941
|
-
'
|
|
936
|
+
'群内发"剑灵提醒订阅"即可让本群收到全部提醒\\n' +
|
|
937
|
+
'命令:剑灵提醒订阅 | 取消剑灵订阅 | 订阅列表 | schedule.list | schedule.test | schedule.debug'
|
|
942
938
|
})
|
|
943
939
|
|
|
944
940
|
ctx.command('schedule.list', '查看活动表')
|
|
@@ -1083,24 +1079,6 @@ function apply(ctx, config) {
|
|
|
1083
1079
|
return `✅ 已向本群测试发送任务 "${name}"`
|
|
1084
1080
|
})
|
|
1085
1081
|
|
|
1086
|
-
ctx.command('schedule.testcur [name:text]', '只向当前群测试发送提醒(不发订阅群)')
|
|
1087
|
-
.action(async ({ session }, name) => {
|
|
1088
|
-
logger.info(`[schedule] 命令被调用: schedule.testcur name=${name || '(第一个)'}`)
|
|
1089
|
-
const actResult = await testActivityToGroup(session, name)
|
|
1090
|
-
if (actResult !== null) return actResult
|
|
1091
|
-
const tasks = config.tasks || {}
|
|
1092
|
-
const task = tasks[name]
|
|
1093
|
-
if (!task) return `未找到任务 "${name}",可用 schedule.list 查看`
|
|
1094
|
-
if (!session.guildId) return '❌ 只能在群里使用'
|
|
1095
|
-
const testTask = { ...task, groups: [String(session.guildId)] }
|
|
1096
|
-
const rows = parseScheduleRows(task)
|
|
1097
|
-
const day = todayDay()
|
|
1098
|
-
const hit = rows.find(r => dayMatches(parseDays(r.wd), day))
|
|
1099
|
-
const sendText = hit ? (hit.text || '') : (rows.length ? (rows[0].text || '') : '')
|
|
1100
|
-
await sendTask(name, testTask, { text: sendText, markdown: task.markdown, onlyBotSid: session.bot?.sid, skipSubs: true })
|
|
1101
|
-
return `✅ 已向当前群测试发送任务 "${name}"(没有发给订阅群)`
|
|
1102
|
-
})
|
|
1103
|
-
|
|
1104
1082
|
// ===== 群内订阅命令 =====
|
|
1105
1083
|
async function isGroupAdmin(session) {
|
|
1106
1084
|
if (!session.guildId || !session.userId) return false
|
|
@@ -1151,20 +1129,20 @@ function apply(ctx, config) {
|
|
|
1151
1129
|
function listSubscribable(session) {
|
|
1152
1130
|
const lines = ['📋 剑灵提醒(订阅一次,全部活动都会收到):', '', activityOverview()]
|
|
1153
1131
|
if (session.bot && session.guildId) {
|
|
1154
|
-
lines.push('', isSubscribed(session) ? '✅
|
|
1132
|
+
lines.push('', isSubscribed(session) ? '✅ 本群已订阅(发送「取消剑灵订阅」可退订)' : '发送「剑灵提醒订阅」即可让本群收到全部提醒')
|
|
1155
1133
|
}
|
|
1156
1134
|
return lines.join('\n')
|
|
1157
1135
|
}
|
|
1158
1136
|
|
|
1159
1137
|
// 列出本群订阅状态
|
|
1160
1138
|
function listMySubs(session) {
|
|
1161
|
-
if (!isSubscribed(session)) return '本群还没有订阅提醒\n
|
|
1162
|
-
return '📋 本群已订阅全部剑灵提醒:\n\n' + activityOverview() + '\n\n
|
|
1139
|
+
if (!isSubscribed(session)) return '本群还没有订阅提醒\n发送「剑灵提醒订阅」即可订阅全部活动提醒'
|
|
1140
|
+
return '📋 本群已订阅全部剑灵提醒:\n\n' + activityOverview() + '\n\n发送「取消剑灵订阅」可退订'
|
|
1163
1141
|
}
|
|
1164
1142
|
|
|
1165
1143
|
async function subscribeCurrentGroup(session) {
|
|
1166
|
-
logger.info('[schedule] 命令被调用:
|
|
1167
|
-
if (!session.guildId || !session.bot) return '❌
|
|
1144
|
+
logger.info('[schedule] 命令被调用: 剑灵提醒订阅')
|
|
1145
|
+
if (!session.guildId || !session.bot) return '❌ 剑灵提醒订阅只能在群聊里使用'
|
|
1168
1146
|
const key = `${session.bot.sid}:${session.guildId}`
|
|
1169
1147
|
const allSubs = getTaskSubs(ALL)
|
|
1170
1148
|
if (allSubs.has(key)) {
|
|
@@ -1178,8 +1156,8 @@ function apply(ctx, config) {
|
|
|
1178
1156
|
}
|
|
1179
1157
|
|
|
1180
1158
|
async function unsubscribeCurrentGroup(session) {
|
|
1181
|
-
logger.info('[schedule] 命令被调用:
|
|
1182
|
-
if (!session.guildId || !session.bot) return '❌
|
|
1159
|
+
logger.info('[schedule] 命令被调用: 取消剑灵订阅')
|
|
1160
|
+
if (!session.guildId || !session.bot) return '❌ 取消剑灵订阅只能在群聊里使用'
|
|
1183
1161
|
const key = `${session.bot.sid}:${session.guildId}`
|
|
1184
1162
|
const allSubs = subs.get(ALL)
|
|
1185
1163
|
if (!allSubs || !allSubs.has(key)) return 'ℹ️ 本群还没有订阅提醒'
|
|
@@ -1189,15 +1167,14 @@ function apply(ctx, config) {
|
|
|
1189
1167
|
return '✅ 本群已取消全部剑灵提醒'
|
|
1190
1168
|
}
|
|
1191
1169
|
|
|
1192
|
-
ctx.command('
|
|
1193
|
-
.action(async ({ session }
|
|
1170
|
+
ctx.command('剑灵提醒订阅', '订阅全部剑灵提醒')
|
|
1171
|
+
.action(async ({ session }) => {
|
|
1194
1172
|
if (!(await checkSubscribePerm(session))) return permDeniedHint()
|
|
1195
|
-
// 兼容旧用法「订阅 任务名」:现在一律按"订阅全部"处理
|
|
1196
1173
|
return await subscribeCurrentGroup(session)
|
|
1197
1174
|
})
|
|
1198
1175
|
|
|
1199
|
-
ctx.command('
|
|
1200
|
-
.action(async ({ session }
|
|
1176
|
+
ctx.command('取消剑灵订阅', '取消本群的全部剑灵提醒')
|
|
1177
|
+
.action(async ({ session }) => {
|
|
1201
1178
|
if (!(await checkSubscribePerm(session))) return permDeniedHint()
|
|
1202
1179
|
return await unsubscribeCurrentGroup(session, taskName)
|
|
1203
1180
|
})
|
|
@@ -1206,7 +1183,7 @@ function apply(ctx, config) {
|
|
|
1206
1183
|
.action(async () => {
|
|
1207
1184
|
logger.info('[schedule] 命令被调用: 订阅列表')
|
|
1208
1185
|
const allSubs = subs.get(ALL)
|
|
1209
|
-
if (!allSubs || !allSubs.size) return '暂无任何群订阅。群内发"
|
|
1186
|
+
if (!allSubs || !allSubs.size) return '暂无任何群订阅。群内发"剑灵提醒订阅"即可订阅全部提醒'
|
|
1210
1187
|
const lines = [`📋 已订阅提醒的群(共 ${allSubs.size} 个):`]
|
|
1211
1188
|
for (const s of allSubs.values()) {
|
|
1212
1189
|
const bot = ctx.bots.find(b => b.sid === s.botSid)
|
|
@@ -1216,51 +1193,6 @@ function apply(ctx, config) {
|
|
|
1216
1193
|
return lines.join('\n')
|
|
1217
1194
|
})
|
|
1218
1195
|
|
|
1219
|
-
// 管理员:取消所有群的提醒订阅(并通知每个被取消的群)
|
|
1220
|
-
ctx.command('schedule.unsuball', '取消所有群的提醒订阅(管理员)')
|
|
1221
|
-
.action(async ({ session }) => {
|
|
1222
|
-
logger.info('[schedule] 命令被调用: schedule.unsuball')
|
|
1223
|
-
// 权限:权限等级 ≥ 3,或(开启群主绕过时)本群群主/群管理
|
|
1224
|
-
const isAdmin = (session.user?.authority >= 3) ||
|
|
1225
|
-
(config.subscribeAdminBypass && await isGroupAdmin(session))
|
|
1226
|
-
if (!isAdmin) return permDeniedHint()
|
|
1227
|
-
|
|
1228
|
-
const allSubs = subs.get(ALL)
|
|
1229
|
-
if (!allSubs || !allSubs.size) return 'ℹ️ 当前没有任何群订阅'
|
|
1230
|
-
const targets = [...allSubs.values()].map(e => ({ botSid: e.botSid, guildId: e.guildId }))
|
|
1231
|
-
|
|
1232
|
-
// 逐群发送"已取消"提示
|
|
1233
|
-
let notified = 0
|
|
1234
|
-
if (config.unsubAllNotice) {
|
|
1235
|
-
for (const t of targets) {
|
|
1236
|
-
const bot = (ctx.bots || []).find(b => b.sid === t.botSid)
|
|
1237
|
-
if (!bot || !bot.online) continue
|
|
1238
|
-
const text = String(config.unsubAllNotice).split('{task}').join('剑灵提醒')
|
|
1239
|
-
try {
|
|
1240
|
-
await bot.sendMessage(t.guildId, [text])
|
|
1241
|
-
notified++
|
|
1242
|
-
}
|
|
1243
|
-
catch (e) {
|
|
1244
|
-
logger.warn(`[schedule] 取消提示发送失败 ${t.botSid}:${t.guildId}: ${e.message}`)
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
|
|
1249
|
-
// 清空订阅(内存 + 数据库)
|
|
1250
|
-
allSubs.clear()
|
|
1251
|
-
for (const k of [...subs.keys()]) if (k !== ALL) subs.delete(k)
|
|
1252
|
-
if (ctx.database) {
|
|
1253
|
-
try {
|
|
1254
|
-
await ctx.database.remove('ll_schedule_subs', {})
|
|
1255
|
-
}
|
|
1256
|
-
catch (e) {
|
|
1257
|
-
logger.warn('[schedule] 清空订阅表失败:', e)
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
logger.info(`[schedule] 已取消 ${targets.length} 个群的订阅(通知 ${notified} 个群)`)
|
|
1261
|
-
return `✅ 已取消 ${targets.length} 个群的订阅\n已向 ${notified} 个群发送取消提示`
|
|
1262
|
-
})
|
|
1263
|
-
|
|
1264
1196
|
ctx.command('我的ID', '查看自己的账号信息(openid/群ID/角色)')
|
|
1265
1197
|
.action(({ session }) => {
|
|
1266
1198
|
logger.info('[schedule] 命令被调用: 我的ID')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-ll-schedule",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.7",
|
|
4
4
|
"description": "Scheduled message sender with weekly slots (per-day time & content), QQ official markdown card support",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -37,4 +37,5 @@
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
|
|
40
|
+
|
|
40
41
|
|