diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ef2cdd3 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,21 @@ +name: Build + +on: + push: + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Check out + uses: actions/checkout@v3 + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: 16 + - name: Install + run: yarn + - name: Build + run: yarn build diff --git a/package.json b/package.json new file mode 100644 index 0000000..f0b4811 --- /dev/null +++ b/package.json @@ -0,0 +1,52 @@ +{ + "name": "koishi-plugin-market-info", + "description": "Koishi plugin market information", + "version": "1.0.0", + "main": "lib/index.js", + "typings": "lib/index.d.ts", + "files": [ + "lib", + "dist" + ], + "author": "Shigma ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/koishijs/koishi-plugin-market-info.git" + }, + "bugs": { + "url": "https://github.com/koishijs/koishi-plugin-market-info/issues" + }, + "homepage": "https://github.com/koishijs/koishi-plugin-market-info#readme", + "scripts": { + "build": "atsc -b" + }, + "koishi": { + "browser": true, + "description": { + "en": "Plugin market information", + "zh": "插件市场信息查询与订阅" + } + }, + "keywords": [ + "chatbot", + "koishi", + "plugin", + "market", + "info", + "subscribe", + "update", + "registry", + "manager" + ], + "peerDependencies": { + "koishi": "^4.10.5" + }, + "devDependencies": { + "@koishijs/registry": "^4.1.6", + "@types/node": "^17.0.45", + "atsc": "^1.2.1", + "koishi": "^4.10.5", + "typescript": "^4.9.3" + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..a2480f5 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,76 @@ +import { Context, Dict, Logger, Schema, Time } from 'koishi' +import type { MarketPackage, MarketResult } from '@koishijs/registry' + +const logger = new Logger('market') + +export const name = 'market-info' + +export interface Rule { + platform: string + channelId: string + selfId?: string + guildId?: string +} + +export const Rule: Schema = Schema.object({ + platform: Schema.string().description('平台名称。').required(), + channelId: Schema.string().description('频道 ID。').required(), + guildId: Schema.string().description('群组 ID。'), + selfId: Schema.string().description('机器人 ID。'), +}) + +export interface Config { + rules: Rule[] + interval: number +} + +export const Config: Schema = Schema.object({ + rules: Schema.array(Rule).description('推送规则。'), + interval: Schema.number().default(Time.minute * 30).description('轮询间隔 (毫秒)。'), +}) + +function makeDict(result: MarketResult) { + const dict: Dict = {} + for (const object of result.objects) { + dict[object.name] = object + } + return dict +} + +export function apply(ctx: Context, config: Config) { + const getMarket = async () => { + const data = await ctx.http.get('https://registry.koishi.chat/market.json') + return makeDict(data) + } + + ctx.on('ready', async () => { + let previous = await getMarket() + + ctx.setInterval(async () => { + const current = await getMarket() + const diff = Object.keys({ ...previous, ...current }).map((name) => { + const version1 = previous[name]?.version + const version2 = current[name]?.version + if (version1 === version2) return + if (!version1) return '新增:' + name + if (!version2) return '移除:' + name + return `更新:${name} (${version1} → ${version2})` + }).filter(Boolean).sort() + previous = current + if (!diff.length) return + + const content = ['[插件市场更新]', ...diff].join('\n') + logger.info(content) + for (let { channelId, platform, selfId, guildId } of config.rules) { + if (!selfId) { + const channel = await ctx.database.getChannel(platform, channelId, ['assignee', 'guildId']) + if (!channel || !channel.assignee) return + selfId = channel.assignee + guildId = channel.guildId + } + const bot = ctx.bots[`${platform}:${selfId}`] + bot?.sendMessage(channelId, content, guildId) + } + }, config.interval) + }) +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8d1fad2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "rootDir": "src", + "outDir": "lib", + "target": "es2020", + "module": "commonjs", + "declaration": true, + "composite": true, + "incremental": true, + "skipLibCheck": true, + "esModuleInterop": true, + "moduleResolution": "node" + }, + "include": [ + "src" + ] +} \ No newline at end of file