koishi-plugin-ll-schedule 1.7.0 → 1.7.1
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 +2 -79
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -364,31 +364,11 @@ exports._test = { parseTimes, todayDay, parseDays, dayMatches, parseScheduleBloc
|
|
|
364
364
|
|
|
365
365
|
// ===== 配置 Schema =====
|
|
366
366
|
|
|
367
|
-
const TaskItem = Schema.object({
|
|
368
|
-
schedule: Schema.string()
|
|
369
|
-
.role('textarea', { rows: [6, 16] })
|
|
370
|
-
.default('')
|
|
371
|
-
.description('📅 日程:多行文本框,直接写整张日程。每个时间段分两段:第一行写 星期 时间,下面几行写内容(可多行 markdown)。示例见 usage。'),
|
|
372
|
-
groups: Schema.array(Schema.string())
|
|
373
|
-
.default([])
|
|
374
|
-
.description('手动指定的目标群 ID(可留空;推荐用群内"订阅"命令自动添加,无需手动填 openid)'),
|
|
375
|
-
markdown: Schema.boolean()
|
|
376
|
-
.default(false)
|
|
377
|
-
.description('用 QQ官方 Markdown 卡片发送(仅官方QQ机器人生效,失败自动回退纯文本;其他平台始终纯文本)'),
|
|
378
|
-
pushTemplate: Schema.string()
|
|
379
|
-
.role('textarea', { rows: [3, 8] })
|
|
380
|
-
.default('')
|
|
381
|
-
.description('接口推送模板(可选):HTTP 接口推送时套用的卡片模板。变量 {place1} {place2} 等 = 推送方传入的字段;留空用默认模板。多行 markdown,例见 usage'),
|
|
382
|
-
enabled: Schema.boolean()
|
|
383
|
-
.default(true)
|
|
384
|
-
.description('是否启用'),
|
|
385
|
-
})
|
|
386
|
-
|
|
387
367
|
const Config = Schema.object({
|
|
388
368
|
activities: Schema.string()
|
|
389
369
|
.role('textarea', { rows: [8, 20] })
|
|
390
370
|
.default('')
|
|
391
|
-
.description('📅 剑灵活动表(全部活动写这里,一份表管所有提醒)。格式:[活动名] 提前:N分钟,下面每行 = 星期 开始-结束 地点:xxx
|
|
371
|
+
.description('📅 剑灵活动表(全部活动写这里,一份表管所有提醒)。格式:[活动名] 提前:N分钟,下面每行 = 星期 开始-结束 地点:xxx'),
|
|
392
372
|
remindTemplate: Schema.string()
|
|
393
373
|
.role('textarea', { rows: [6, 14] })
|
|
394
374
|
.default('')
|
|
@@ -399,12 +379,6 @@ const Config = Schema.object({
|
|
|
399
379
|
globalGroups: Schema.array(Schema.string())
|
|
400
380
|
.default([])
|
|
401
381
|
.description('额外固定推送群(可选):这些群无需订阅也会收到活动提醒(留空即可,一般用群内"订阅"命令)'),
|
|
402
|
-
tasks: Schema.dict(TaskItem)
|
|
403
|
-
.default({})
|
|
404
|
-
.description('📋 旧版推送任务表格(活动表 activities 为空时生效;每个任务 = 一个日程大文本框 schedule:星期/时间/内容)'),
|
|
405
|
-
pushSecret: Schema.string()
|
|
406
|
-
.default('')
|
|
407
|
-
.description('🔑 HTTP 推送接口密钥:外部系统调用 POST /ll-schedule/push 时须携带相同 secret(留空则接口拒绝所有推送)'),
|
|
408
382
|
unsubAllNotice: Schema.string()
|
|
409
383
|
.default('本群已取消剑灵提醒推送')
|
|
410
384
|
.description('管理员用 schedule.unsuball 取消全部订阅时,发到每个被取消群的提示语(留空则不发送提示)'),
|
|
@@ -758,58 +732,7 @@ function apply(ctx, config) {
|
|
|
758
732
|
}
|
|
759
733
|
}
|
|
760
734
|
|
|
761
|
-
// =====
|
|
762
|
-
if (ctx.router) {
|
|
763
|
-
ctx.router.post('/ll-schedule/push', async (ctx) => {
|
|
764
|
-
const respond = (status, body) => { ctx.status = status; ctx.body = body }
|
|
765
|
-
let body = null
|
|
766
|
-
try {
|
|
767
|
-
body = (typeof ctx.request.body === 'string') ? JSON.parse(ctx.request.body) : (ctx.request.body || {})
|
|
768
|
-
}
|
|
769
|
-
catch (e) {
|
|
770
|
-
return respond(400, { ok: false, error: 'invalid json body' })
|
|
771
|
-
}
|
|
772
|
-
// 密钥校验(未配置密钥则一律拒绝)
|
|
773
|
-
if (!config.pushSecret) return respond(403, { ok: false, error: 'pushSecret not configured' })
|
|
774
|
-
if (body.secret !== config.pushSecret) return respond(403, { ok: false, error: 'invalid secret' })
|
|
775
|
-
|
|
776
|
-
const taskName = String(body.task || '')
|
|
777
|
-
const task = (config.tasks || {})[taskName]
|
|
778
|
-
if (!taskName || !task) return respond(404, { ok: false, error: `task "${taskName}" not found` })
|
|
779
|
-
|
|
780
|
-
// 除 secret/task/delay 外的字段都作为模板变量(place1/place2/time/...)
|
|
781
|
-
const data = { ...body }
|
|
782
|
-
delete data.secret
|
|
783
|
-
delete data.task
|
|
784
|
-
delete data.delay
|
|
785
|
-
const now = new Date()
|
|
786
|
-
const rendered = renderPushTemplate(task.pushTemplate, data, {
|
|
787
|
-
date: todayStr(now),
|
|
788
|
-
time: nowHM(now),
|
|
789
|
-
week: '星期' + WEEK_CN[todayDay(now)],
|
|
790
|
-
task: taskName,
|
|
791
|
-
})
|
|
792
|
-
if (!rendered.trim()) return respond(400, { ok: false, error: 'empty content' })
|
|
793
|
-
|
|
794
|
-
const delay = Math.max(0, parseInt(body.delay, 10) || 0)
|
|
795
|
-
const push = async () => {
|
|
796
|
-
// 只发给订阅群(含手动 groups),不发全量已知群
|
|
797
|
-
await sendTask(taskName, task, { text: rendered, markdown: task.markdown })
|
|
798
|
-
}
|
|
799
|
-
if (delay > 0) {
|
|
800
|
-
setTimeout(push, delay * 60 * 1000)
|
|
801
|
-
logger.info(`[schedule] 接口已接收任务 "${taskName}",${delay} 分钟后推送`)
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
await push()
|
|
805
|
-
logger.info(`[schedule] 接口已推送任务 "${taskName}"`)
|
|
806
|
-
}
|
|
807
|
-
return respond(200, { ok: true, delay, task: taskName })
|
|
808
|
-
})
|
|
809
|
-
logger.info('[schedule] HTTP 推送接口已注册: POST /ll-schedule/push')
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
// ===== 活动提醒(新:活动表模式)=====
|
|
735
|
+
// ===== 活动提醒(活动表模式)=====
|
|
813
736
|
|
|
814
737
|
// 发给所有"订阅了全部提醒"的群(+ 额外固定群)
|
|
815
738
|
async function sendToSubscribers(text, { markdown, image } = {}) {
|
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.1",
|
|
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": [
|
|
@@ -32,3 +32,4 @@
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
|