feat: add basic impl
This commit is contained in:
		
							parent
							
								
									6d6e333016
								
							
						
					
					
						commit
						6251df10b1
					
				
							
								
								
									
										21
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||||
							
								
								
									
										52
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -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 <shigma10826@gmail.com>", | ||||||
|  |   "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" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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<Rule> = 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<Config> = Schema.object({ | ||||||
|  |   rules: Schema.array(Rule).description('推送规则。'), | ||||||
|  |   interval: Schema.number().default(Time.minute * 30).description('轮询间隔 (毫秒)。'), | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | function makeDict(result: MarketResult) { | ||||||
|  |   const dict: Dict<MarketPackage> = {} | ||||||
|  |   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<MarketResult>('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) | ||||||
|  |   }) | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -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" | ||||||
|  |   ] | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user