都可以开源的,只是懒,没有提交 github
import { Context, Schema, Session } from 'koishi'
import fs from 'fs'
import path from 'path'
export const name = 'smmcat-timingpush'
export const usage = `
定时文件格式如下:
\`\`\`
{
"12:00": {
"1011033": ["中午好啊,要吃饭咯"],
"1101111": ["中午好啊,要吃饭咯"],
},
"22:00": {
"1011033": ["10点了,要睡觉咯", "请睡觉吧,不早了"],
}
}
\`\`\`
`
export interface Config {
questPath: string
}
export const Config: Schema<Config> = Schema.object({
questPath: Schema.string().default('./data/smm_scheduledTask').description('任务执行信息路径')
})
export function apply(ctx: Context, config: Config) {
// 任务队列
let scheduledTaskList = {}
function init() {
const initPath = path.join(ctx.baseDir, config.questPath);
console.log("定时任务初始化完成");
if (!fs.existsSync(initPath)) {
fs.mkdirSync(initPath, { recursive: true })
fs.writeFileSync(path.join(initPath, 'init.json'), '{}', 'utf-8')
console.log('定时推送文件已创建');
}
let content = fs.readFileSync(path.join(initPath, 'init.json'), 'utf-8');
scheduledTaskList = content ? JSON.parse(content) : {};
}
function setLocalStoreData() {
const initPath = path.join(ctx.baseDir, config.questPath, 'init.json')
// 创建文件并写入内容
fs.writeFileSync(initPath, JSON.stringify(scheduledTaskList), 'utf-8')
console.log('更新内容完成');
}
// 写入数据
function setData(params: { time: string, guildId: string, msg: string[] }) {
const { time, guildId, msg } = params
if (![time, guildId, msg].every(item => item)) return { code: false, msg: "缺少必要参数" }
if (!scheduledTaskList[time]) {
scheduledTaskList[time] = {}
}
if (!scheduledTaskList[time][guildId]) {
scheduledTaskList[time][guildId] = []
}
scheduledTaskList[time][guildId].push(...msg)
setLocalStoreData()
return { code: true, msg: "添加成功" }
}
// 删除数据
function delData(params: { time: string, guildId: string }) {
const { time, guildId } = params
if (![time, guildId].every(item => item)) return { code: false, msg: "缺少必要参数" }
if (!scheduledTaskList[time]) {
return { code: false, msg: "没有该时间段的事件" }
}
if (!scheduledTaskList[time][guildId]) {
return { code: false, msg: "该时间段没有本群的定时任务" }
}
delete scheduledTaskList[time][guildId]
setLocalStoreData()
return { code: true, msg: "删除成功" }
}
// 查询数据
function checkData(params: { guildId: string }) {
const { guildId } = params
if (![guildId].every(item => item)) return { code: false, msg: "缺少必要参数" }
const temp = {}
Object.keys(scheduledTaskList).forEach((time) => {
Object.keys(scheduledTaskList[time]).forEach((qun) => {
if (qun == guildId) {
if (!temp[time]) {
temp[time] = {}
}
temp[time][qun] = scheduledTaskList[time][qun]
}
})
})
const msg = Object.keys(temp).map((time) => {
return Object.keys(temp[time]).map((qun) => {
return `时间:${time}\n\n分发内容:${temp[time][qun].join('\n')}`
}).join('\n')
}).join('\n------------------------\n')
return { code: true, msg: msg.length ? msg : '当前还没有定时事项' }
}
const userOrder = {
setData,
delData,
checkData
}
// 定时业务
const scheduledTask = {
timer: null,
// 定时任务队列
async createScheduledTask() {
// 创建定时任务
console.log("启动定时任务");
this.timer = ctx.setInterval(() => {
// 查看是否存在任务
scheduledTask.checkScheduledTask()
}, 60000)
},
// 格式化时间
formatTime(time: Date): string {
const hours = time.getHours().toString().padStart(2, '0')
const minutes = time.getMinutes().toString().padStart(2, '0')
return `${hours}:${minutes}`
},
// 判断当前是否存在任务
checkScheduledTask() {
const time = new Date()
// 获取当前时间字符值
const keys = this.formatTime(time)
console.log(keys, scheduledTaskList[keys]);
// 存在事件时
if (scheduledTaskList[keys]) {
// 遍历需要发送群与要发送的内容
Object.keys(scheduledTaskList[keys]).map((item) => {
// 获取消息内容
const msgList = scheduledTaskList[keys][item]
const msg = msgList[Math.floor(Math.random() * msgList.length)]
// 随机发送预设中的内容
console.log('推送消息群:' + item);
console.log('推送的消息:' + msg);
ctx.bots[0].sendMessage(item, msg);
})
}
},
// 清除定时任务
clearScheduledTask() {
if (this.timer) {
this.timer && this.timer()
this.timer = null
}
}
}
ctx
.command('取消推送')
.action(async ({ session }) => {
if (!scheduledTask.timer) {
await session.send('未开启定时推送,取消失败')
}
scheduledTask.clearScheduledTask()
})
ctx
.command('开始推送')
.action(async ({ session }) => {
if (scheduledTask.timer) {
await session.send('已开启定时推送,无需再次开启')
}
scheduledTask.createScheduledTask()
})
ctx
.command('查询推送')
.action(async ({ session }) => {
if (!checkIsGuild(session)) {
return '该命令只能在群组内使用'
}
const data = userOrder.checkData({ guildId: session.guildId })
if (!data.code) {
return `[×] ` + data.msg
}
return `[√] ` + data.msg
})
ctx
.command('添加推送 <time> <msg>')
.action(async ({ session }, time, msg) => {
if (!checkIsGuild(session)) {
return '该命令只能在群组内使用'
}
if (!time) return `请输入时间。例如格式 /添加推送 12:00 内容`
if (!msg) return `请输入定时需要推送的消息,例如格式 /添加推送 12:00 内容`
const data = userOrder.setData({ guildId: session.guildId, time, msg: [msg] })
if (!data.code) {
return `[×] ` + data.msg
}
return `[√] ` + data.msg
})
ctx
.command('删除推送 <time>')
.action(async ({ session }, time) => {
if (!checkIsGuild(session)) {
return '该命令只能在群组内使用'
}
if (!time) return `请输入时间。例如格式 /删除推送 12:00`
const data = userOrder.delData({ guildId: session.guildId, time })
if (!data.code) {
return `[×] ` + data.msg
}
return `[√] ` + data.msg
})
// 是否为群内操作
function checkIsGuild(session: Session) {
if (session.guildId) return true
return false
}
ctx.on('ready', async () => {
try {
await init()
scheduledTask.createScheduledTask()
} catch (err) {
ctx.logger('smmcat-timingpush').error(err)
}
})
}