diff --git a/core/package.json b/core/package.json index 53659698..f5fc587c 100644 --- a/core/package.json +++ b/core/package.json @@ -30,7 +30,8 @@ "jiti": "^1.21.0", "log4js": "^6.9.1", "tsconfig-paths": "^4.2.0", - "yaml": "^2.4.5" + "yaml": "^2.4.5", + "smol-toml": "^1.3.1" }, "peerDependencies": { "@zhinjs/shared": "workspace:^" diff --git a/core/src/adapter.ts b/core/src/adapter.ts index 0b835148..33679c9a 100644 --- a/core/src/adapter.ts +++ b/core/src/adapter.ts @@ -12,7 +12,6 @@ export type Element = { data: Dict; }; export class Adapter

extends EventEmitter { - bots: Adapter.Bot

[] = []; elements: Element[] = []; private [adapterKey] = true; #is_started: boolean = false; @@ -21,6 +20,18 @@ export class Adapter

extends EventEmitter { static isAdapter(obj: any): obj is Adapter { return typeof obj === 'object' && !!obj[adapterKey]; } + get bots(): Adapter.Bot

[] { + return (this.app?.bots.filter(bot => bot.adapter === this) || []) as unknown as Adapter.Bot

[]; + } + set bots(bots: Adapter.Bot

[]) { + for (const bot of bots) { + if (bot.adapter !== this) throw new Error(`bot ${bot.unique_id} not belongs to adapter ${this.name}`); + const hasBot = (bot: Adapter.Bot

) => { + return this.app?.bots.some(b => b.unique_id === bot.unique_id); + }; + if (!hasBot(bot)) this.app?.bots.push(bot as any); + } + } start(app: App, config: Adapter.BotConfig

[]) { this.app = app; this.emit('start', config); @@ -89,64 +100,46 @@ export class Adapter

extends EventEmitter { export interface Adapter

{ on>(event: T, listener: Adapter.EventMap

[T]): this; - on( - event: S & Exclude>, - listener: (...args: any[]) => any, - ): this; + on(event: S & Exclude>, listener: (...args: any[]) => any): this; - off>(event: T, callback?: Adapter.EventMap

[T]): this; + off>(event: T, listener?: Adapter.EventMap

[T]): this; - off( - event: S & Exclude>, - callback?: (...args: any[]) => void, - ): this; + off(event: S & Exclude>, callback?: (...args: any[]) => void): this; once>(event: T, listener: Adapter.EventMap

[T]): this; - once( - event: S & Exclude>, - listener: (...args: any[]) => any, - ): this; + once(event: S & Exclude>, listener: (...args: any[]) => any): this; emit>(event: T, ...args: Parameters[T]>): boolean; - emit( - event: S & Exclude>, - ...args: any[] - ): boolean; + emit(event: S & Exclude>, ...args: any[]): boolean; addListener>(event: T, listener: Adapter.EventMap

[T]): this; - addListener( - event: S & Exclude>, + addListener( + event: S & Exclude>, listener: (...args: any[]) => any, ): this; addListenerOnce>(event: T, callback: Adapter.EventMap

[T]): this; - addListenerOnce( - event: S & Exclude>, + addListenerOnce( + event: S & Exclude>, callback: (...args: any[]) => void, ): this; removeListener>(event: T, callback?: Adapter.EventMap

[T]): this; - removeListener( - event: S & Exclude>, + removeListener( + event: S & Exclude>, callback?: (...args: any[]) => void, ): this; removeAllListeners>(event: T): this; - removeAllListeners(event: S & Exclude>): this; + removeAllListeners(event: S & Exclude>): this; } export namespace Adapter { - export interface EventMap

{ - 'bot-ready'(bot: Bot

): void; - 'start'(configs: BotConfig

[]): void; - 'stop'(): void; - } - export type Bot

= BaseBot

& App.Clients[P]; export abstract class BaseBot

{ protected constructor( public adapter: Adapter

, @@ -154,6 +147,12 @@ export namespace Adapter { public client: App.Clients[P], ) { const _this = this; + const oldEmit = client.emit; + client.emit = function (event: string, ...args: any[]) { + const result = oldEmit.apply(client, [event, ...args] as any); + _this.adapter.app?.emit(`${_this.adapter.name}.${event}`, _this, ...args); + return result; + } as typeof oldEmit; return new Proxy(_this, { get(target, prop, receiver) { if (prop in target) return Reflect.get(target, prop, receiver); @@ -176,6 +175,12 @@ export namespace Adapter { return this.adapter.botConfig(this.unique_id)?.forward_length; } } + export type Bot

= BaseBot

& App.Clients[P]; + export interface EventMap

{ + 'bot-ready': (bot: Bot

) => void; + 'start': (configs: BotConfig

[]) => void; + 'stop': () => void; + } export function load(name: string) { const maybePath = [ path.join(WORK_DIR, 'node_modules', `@zhinjs`, name), // 官方适配器 diff --git a/core/src/app.ts b/core/src/app.ts index 066c6cea..31d5e7c3 100644 --- a/core/src/app.ts +++ b/core/src/app.ts @@ -5,7 +5,7 @@ import { Plugin, PluginMap } from './plugin'; import { LogLevel } from './types'; import { loadModule } from './utils'; import { remove, sleep } from '@zhinjs/shared'; -import { APP_KEY, CONFIG_DIR, serviceCallbacksKey, WORK_DIR } from './constans'; +import { APP_KEY, CONFIG_DIR, WORK_DIR } from './constans'; import path from 'path'; import { Adapter } from './adapter'; import { Message } from './message'; @@ -29,6 +29,7 @@ export class App extends EventEmitter { middlewares: Middleware[] = []; plugins: PluginMap = new PluginMap(); renders: Message.Render[] = []; + bots: Adapter.Bot[] = []; get adapters() { return App.adapters; } @@ -178,6 +179,7 @@ export class App extends EventEmitter { emit(event: string, ...args: any[]) { const result = super.emit(event, ...args); + this.logger.debug(`emit event: ${event}`); for (const plugin of this.pluginList) { plugin.emit(event, ...args); } @@ -274,12 +276,11 @@ export class App extends EventEmitter { for (const loadPath of maybePath) { if (loaded) break; try { - this.logger.debug(`try load plugin(${name}) from ${loadPath}`); this.mount(loadPath); loaded = true; } catch (e) { if (!error || String(Reflect.get(error, 'message')).startsWith('Cannot find')) error = e as Error; - this.logger.debug(`try load plugin(${name}) failed. (from: ${loadPath})`, (e as Error)?.message || e); + this.logger.trace(`try load plugin(${name}) failed. (from: ${loadPath})`, (e as Error)?.message || e); } } if (!loaded) this.logger.warn(`load plugin "${name}" failed`, error?.message || error); @@ -394,7 +395,7 @@ export namespace App { title: string; }; } - export interface Clients { + export interface Clients extends Record { process: NodeJS.Process; } export interface Services {} diff --git a/core/src/config.ts b/core/src/config.ts index 12bedd95..6e983528 100644 --- a/core/src/config.ts +++ b/core/src/config.ts @@ -1,10 +1,11 @@ import * as fs from 'fs'; import * as path from 'path'; +import smolToml from 'smol-toml'; import * as yaml from 'yaml'; import { CONFIG_DIR } from './constans'; import { App } from './app'; export class Config { - public static exts: string[] = ['.json', '.yaml', '.yml']; + public static exts: string[] = ['.cts', '.mts', '.ts', '.cjs', '.mjs', '.js', '.json', '.yaml', '.yml', '.toml']; filename: string = ''; #type: Config.Type = Config.Type.YAML; private _data: T; @@ -20,6 +21,7 @@ export class Config { if (!Config.exts.includes(ext)) this.filename = path.join(CONFIG_DIR, `${name}${this.#resolveExt()}`); this.#saveConfig(defaultValue); } + this.#type = Config.resolveType(path.extname(this.filename)); this._data = this.#loadConfig(); return new Proxy(this._data, { get: (target, p, receiver) => { @@ -59,8 +61,6 @@ export class Config { if (!fs.existsSync(name)) { throw new Error(`未找到配置文件${name}`); } - const ext = path.extname(name); - this.#type = ['.yaml', '.yml'].includes(ext) ? Config.Type.YAML : Config.Type.JSON; return name; } #resolveExt() { @@ -69,6 +69,12 @@ export class Config { return '.json'; case Config.Type.YAML: return '.yml'; + case Config.Type.TOML: + return '.toml'; + case Config.Type.JS: + return '.js'; + case Config.Type.TS: + return '.ts'; default: throw new Error(`不支持的配置文件类型${this.#type}`); } @@ -80,6 +86,11 @@ export class Config { return JSON.parse(content); case Config.Type.YAML: return yaml.parse(content); + case Config.Type.TOML: + return smolToml.parse(content); + case Config.Type.JS: + case Config.Type.TS: + return require(this.filename).default; default: throw new Error(`不支持的配置文件类型${this.#type}`); } @@ -90,6 +101,11 @@ export class Config { return fs.writeFileSync(this.filename, JSON.stringify(data, null, 2)); case Config.Type.YAML: return fs.writeFileSync(this.filename, yaml.stringify(data)); + case Config.Type.TOML: + return fs.writeFileSync(this.filename, smolToml.stringify(data)); + case Config.Type.JS: + case Config.Type.TS: + return fs.writeFileSync(this.filename, `export default ${JSON.stringify(data, null, 2)}`); default: throw new Error(`不支持的配置文件类型${this.#type}`); } @@ -124,6 +140,30 @@ export namespace Config { export enum Type { JSON = 'json', YAML = 'yaml', + TOML = 'toml', + TS = 'ts', + JS = 'js', + } + export function resolveType(ext: string): Config.Type { + switch (ext) { + case '.json': + return Config.Type.JSON; + case '.yaml': + case '.yml': + return Config.Type.YAML; + case '.toml': + return Config.Type.TOML; + case '.ts': + case '.cts': + case '.mts': + return Config.Type.TS; + case '.js': + case '.cjs': + case '.mjs': + return Config.Type.JS; + default: + throw new Error(`不支持的配置文件类型${ext}`); + } } } export interface Config extends App.Config {} diff --git a/core/src/message.ts b/core/src/message.ts index ac17a0ab..ef1b9f69 100644 --- a/core/src/message.ts +++ b/core/src/message.ts @@ -24,6 +24,14 @@ export class Message

{ message_base: MessageBase, ) { Object.assign(this, message_base); + const permissions: Set = new Set(this.sender.permissions); + if (adapter.botConfig(bot.unique_id)?.master === this.sender.user_id) { + permissions.add('master'); + } + if (adapter.botConfig(bot.unique_id)?.admins?.includes(this.sender.user_id!)) { + permissions.add('admin'); + } + this.sender.permissions = [...permissions]; } get group_id() { if (this.message_type !== 'group') return undefined; diff --git a/packages/adapters/com-wechat/src/client.ts b/packages/adapters/com-wechat/src/client.ts index 63efb60a..6632a7ef 100644 --- a/packages/adapters/com-wechat/src/client.ts +++ b/packages/adapters/com-wechat/src/client.ts @@ -86,7 +86,7 @@ export class Client extends EventEmitter { if (['path', 'event_path'].includes(key)) server.on('connection', (ws, req) => { this.logger.info(`已连接到协议端:${req.socket.remoteAddress}`); - this.adapter.emit('bot-ready', this); + this.emit('ready', this); ws.on('error', err => { this.logger.error('连接出错:', err); }); @@ -113,7 +113,7 @@ export class Client extends EventEmitter { }); this.ws.on('open', () => { this.logger.mark(`connected to ${config.url}`); - this.adapter.emit('bot-ready', this); + this.emit('ready', this); this.reTryCount = 0; }); this.ws.on('message', this.dispatch); diff --git a/packages/adapters/com-wechat/src/index.ts b/packages/adapters/com-wechat/src/index.ts index 115d94fb..066f7cd2 100644 --- a/packages/adapters/com-wechat/src/index.ts +++ b/packages/adapters/com-wechat/src/index.ts @@ -25,6 +25,9 @@ adapter.schema({ class WechatClient extends Adapter.BaseBot<'com-wechat'> { constructor(config: Adapter.BotConfig<'com-wechat'>) { super(adapter, config.unique_id, new Client(adapter, config, adapter.app!.router)); + this.on('ready', () => { + this.adapter.emit('bot-ready', this); + }); } async handleSendMessage( channel: Message.Channel, @@ -59,18 +62,12 @@ const startBots = (configs: Adapter.BotConfig<'com-wechat'>[]) => { } }; const messageHandler = (bot: WechatClient, event: ClientMessage) => { - const master = bot.config?.master; - const admins = bot.config.admins?.filter(Boolean) || []; const message = Message.from(adapter, bot, { channel: `${event.detail_type}:${event.user_id}`, sender: { user_id: event.user_id, user_name: event.nickname || '', - permissions: [ - master && event.user_id === master && 'master', - admins && admins.includes(event.user_id) && 'admins', - ...(event.permissions || []), - ].filter(Boolean) as string[], + permissions: [...(event.permissions || [])].filter(Boolean) as string[], }, raw_message: ClientMessage.formatToString(event.message), message_type: event.detail_type as any, diff --git a/packages/adapters/dingtalk/src/index.ts b/packages/adapters/dingtalk/src/index.ts index f6a75a97..cb3ef40c 100644 --- a/packages/adapters/dingtalk/src/index.ts +++ b/packages/adapters/dingtalk/src/index.ts @@ -57,18 +57,13 @@ const startBots = (configs: Adapter.BotConfig<'dingtalk'>[]) => { } }; const messageHandler = (bot: Adapter.Bot<'dingtalk'>, event: DingMsgEvent) => { - const master = dingTalkAdapter.botConfig(bot.unique_id)?.master; - const admins = dingTalkAdapter.botConfig(bot.unique_id)?.admins?.filter(Boolean) || []; const message = Message.from(dingTalkAdapter, bot, { raw_message: sendableToString(event.message).trim(), channel: `${event.message_type}:${event instanceof PrivateMessageEvent ? event.user_id : event.group_id}`, message_type: event.message_type, sender: { ...event.sender, - permissions: [ - master && event.user_id === master && 'master', - admins && admins.includes(event.user_id) && 'admins', - ].filter(Boolean) as string[], + permissions: [], }, }); dingTalkAdapter.app!.emit('message', dingTalkAdapter, bot, message); diff --git a/packages/adapters/discord/src/index.ts b/packages/adapters/discord/src/index.ts index 31161c54..e664c0dd 100644 --- a/packages/adapters/discord/src/index.ts +++ b/packages/adapters/discord/src/index.ts @@ -58,18 +58,12 @@ const startBots = (configs: Adapter.BotConfig<'discord'>[]) => { } }; const messageHandler = (bot: Adapter.Bot<'discord'>, event: DiscordMessageEvent) => { - const master = discordAdapter.botConfig(bot.unique_id)?.master; - const admins = discordAdapter.botConfig(bot.unique_id)?.admins?.filter(Boolean) || []; const message = Message.from(discordAdapter, bot, { channel: `${event.message_type}:${event instanceof DirectMessageEvent ? event.user_id : event.channel_id}`, sender: { user_id: event.sender.user_id, user_name: event.sender.user_name, - permissions: [ - ...(event.sender?.permissions as unknown as string[]), - master && event.sender?.user_id === master && 'master', - admins && admins.includes(event.sender.user_id) && 'admins', - ].filter(Boolean) as string[], + permissions: [...(event.sender?.permissions as unknown as string[])].filter(Boolean) as string[], }, raw_message: sendableToString(event.message).trim(), message_type: event.message_type, diff --git a/packages/adapters/email/src/client.ts b/packages/adapters/email/src/client.ts index 47ae7392..633cec40 100644 --- a/packages/adapters/email/src/client.ts +++ b/packages/adapters/email/src/client.ts @@ -169,10 +169,7 @@ export namespace Client { sender: { user_id: from_id.slice(0, -1), user_name: nickname.slice(1), - permissions: [ - this.adapter.botConfig(this.unique_id)?.master === from_id.slice(0, -1) && 'master', - this.adapter.botConfig(this.unique_id)?.admins?.includes(from_id.slice(1)) && 'admins', - ].filter(Boolean) as string[], + permissions: [], }, }; } diff --git a/packages/adapters/icqq/src/utils.ts b/packages/adapters/icqq/src/utils.ts index b6f8638a..df5ffef3 100644 --- a/packages/adapters/icqq/src/utils.ts +++ b/packages/adapters/icqq/src/utils.ts @@ -61,6 +61,7 @@ function createMessageBaseForGuild(event: GuildMessageEvent): MessageBase { sender: { user_id: event.sender.tiny_id, user_name: event.sender.nickname, + permissions: [], }, raw_message: event.raw_message, }; @@ -90,6 +91,7 @@ export function createMessageBase(event: QQMessageEvent): MessageBase { sender: { user_id: event.sender.user_id, user_name: event.sender.nickname, + permissions: [], }, quote: event.source ? createPrivateQuote(event) : undefined, raw_message: event.raw_message, @@ -102,6 +104,7 @@ export function createMessageBase(event: QQMessageEvent): MessageBase { sender: { user_id: event.sender.user_id, user_name: event.sender.nickname, + permissions: [event.member.is_owner ? 'owner' : '', event.member.is_admin ? 'admin' : ''].filter(Boolean), }, raw_message: event.raw_message, quote: event.source ? createGroupQuote(event) : undefined, @@ -114,6 +117,7 @@ export function createMessageBase(event: QQMessageEvent): MessageBase { sender: { user_id: event.sender.user_id, user_name: event.sender.nickname, + permissions: [], }, raw_message: event.raw_message, }; diff --git a/packages/adapters/kritor/src/index.ts b/packages/adapters/kritor/src/index.ts index d7246456..033ebcc3 100644 --- a/packages/adapters/kritor/src/index.ts +++ b/packages/adapters/kritor/src/index.ts @@ -37,8 +37,6 @@ class KritorClient extends Adapter.BaseBot<'kritor'> { } interface KritorClient extends Client {} const messageHandler = (bot: Adapter.Bot<'kritor'>, event: kritor.common.IPushMessageBody) => { - const master = adapter.botConfig(bot.unique_id)?.master; - const admins = adapter.botConfig(bot.unique_id)?.admins?.filter(Boolean) || []; const message = Message.from(adapter, bot, { raw_message: Client.eventMessageToString(event), message_type: Client.getMessageType(event) as Message.Type, @@ -48,10 +46,7 @@ const messageHandler = (bot: Adapter.Bot<'kritor'>, event: kritor.common.IPushMe sender: { user_id: event.sender?.uid!, user_name: event.sender?.nick || '', - permissions: [ - master && event.sender?.uid === master && 'master', - admins && admins.includes(event.sender?.uid || '') && 'admins', - ].filter(Boolean) as string[], + permissions: [], }, }); bot.logger.info(`recv [${message.channel})]: ${message.raw_message}`); diff --git a/packages/adapters/onebot-11/src/index.ts b/packages/adapters/onebot-11/src/index.ts index 9c626425..3cf15c8c 100644 --- a/packages/adapters/onebot-11/src/index.ts +++ b/packages/adapters/onebot-11/src/index.ts @@ -24,6 +24,9 @@ oneBotV11.schema({ class OneBotClient extends Adapter.BaseBot<'onebot-11'> { constructor(config: Adapter.BotConfig<'onebot-11'>) { super(oneBotV11, config.unique_id, new OneBotV11(oneBotV11, config, oneBotV11.app!.router)); + this.on('ready', () => { + this.adapter.emit('bot-ready', this); + }); } async handleSendMessage( channel: Message.Channel, @@ -58,18 +61,13 @@ const startBots = (configs: Adapter.BotConfig<'onebot-11'>[]) => { } }; const messageHandler = (bot: OneBotClient, event: MessageV11) => { - const master = oneBotV11.botConfig(bot.unique_id)?.master; - const admins = oneBotV11.botConfig(bot.unique_id)?.admins?.filter(Boolean) || []; const message = Message.from(oneBotV11, bot, { raw_message: MessageV11.formatToString(event.message), channel: `${event.message_type}:${event.message_type === 'private' ? event.user_id : event.group_id}`, sender: { user_id: event.sender?.user_id, user_name: event.sender?.nickname || '', - permissions: [ - master && event.user_id === master && 'master', - admins && admins.includes(event.user_id) && 'admins', - ].filter(Boolean) as string[], + permissions: [], }, message_type: event.message_type, }); diff --git a/packages/adapters/onebot-11/src/onebot.ts b/packages/adapters/onebot-11/src/onebot.ts index 7e50e816..e3986f04 100644 --- a/packages/adapters/onebot-11/src/onebot.ts +++ b/packages/adapters/onebot-11/src/onebot.ts @@ -72,7 +72,7 @@ export class OneBotV11 extends EventEmitter { if (['path', 'event_path'].includes(key)) server.on('connection', (ws, req) => { this.logger.info(`已连接到协议端:${req.socket.remoteAddress}`); - this.adapter.emit('bot-ready', this); + this.emit('ready'); ws.on('error', err => { this.logger.error('连接出错:', err); }); diff --git a/packages/adapters/onebot-12/src/index.ts b/packages/adapters/onebot-12/src/index.ts index 15f1101f..1329e602 100644 --- a/packages/adapters/onebot-12/src/index.ts +++ b/packages/adapters/onebot-12/src/index.ts @@ -24,6 +24,9 @@ oneBotV12Adapter.schema({ class OneBotClient extends Adapter.BaseBot<'onebot-12'> { constructor(config: Adapter.BotConfig<'onebot-12'>) { super(oneBotV12Adapter, config.unique_id, new OneBotV12(oneBotV12Adapter, config, oneBotV12Adapter.app!.router)); + this.on('ready', () => { + this.adapter.emit('bot-ready', this); + }); } async handleSendMessage( channel: Message.Channel, @@ -58,8 +61,6 @@ const startBots = (configs: Adapter.BotConfig<'onebot-12'>[]) => { } }; const messageHandler = (bot: OneBotClient, event: MessageV12) => { - const master = bot.config?.master; - const admins = bot.config.admins?.filter(Boolean) || []; const message = Message.from(oneBotV12Adapter, bot, { message_id: event.message_id, channel: `${event.detail_type}:${event.group_id || event.user_id || event.guild_id}`, @@ -67,10 +68,7 @@ const messageHandler = (bot: OneBotClient, event: MessageV12) => { sender: { user_id: event.sender.user_id, user_name: event.sender.nickname || '', - permissions: [ - master && event.sender.user_id === master && 'master', - admins && admins.includes(event.sender.user_id) && 'admins', - ].filter(Boolean) as string[], + permissions: [], }, raw_message: MessageV12.formatToString(event.message), }); diff --git a/packages/adapters/onebot-12/src/onebot.ts b/packages/adapters/onebot-12/src/onebot.ts index 0414a7dd..b22662e6 100644 --- a/packages/adapters/onebot-12/src/onebot.ts +++ b/packages/adapters/onebot-12/src/onebot.ts @@ -84,7 +84,7 @@ export class OneBotV12 extends EventEmitter { if (['path', 'event_path'].includes(key)) server.on('connection', (ws, req) => { this.logger.info(`已连接到协议端:${req.socket.remoteAddress}`); - this.adapter.emit('bot-ready', this); + this.emit('ready'); ws.on('error', err => { this.logger.error('连接出错:', err); }); @@ -111,7 +111,7 @@ export class OneBotV12 extends EventEmitter { }); this.ws.on('open', () => { this.logger.mark(`connected to ${config.url}`); - this.adapter.emit('bot-ready', this); + this.emit('ready'); this.reTryCount = 0; }); this.ws.on('message', this.dispatch); diff --git a/packages/adapters/qq/src/index.ts b/packages/adapters/qq/src/index.ts index 626f9ab7..3d963014 100644 --- a/packages/adapters/qq/src/index.ts +++ b/packages/adapters/qq/src/index.ts @@ -119,19 +119,13 @@ const createChannel = (event: QQMessageEvent): Message.Channel => { } }; const messageHandler = (bot: QQClient, event: QQMessageEvent) => { - const master = qqAdapter.botConfig(bot.unique_id)?.master; - const admins = qqAdapter.botConfig(bot.unique_id)?.admins?.filter(Boolean) || []; const message = Message.from(qqAdapter, bot, { raw_message: sendableToString(event.message).trim(), message_type: event.message_type, channel: createChannel(event), sender: { ...event.sender, - permissions: [ - master && event.user_id === master && 'master', - admins && admins.includes(event.user_id) && 'admins', - ...event.sender?.permissions, - ].filter(Boolean) as string[], + permissions: [], }, }); if (event.source) { diff --git a/packages/adapters/web-wechat/src/index.ts b/packages/adapters/web-wechat/src/index.ts index bada39ee..b6ed1176 100644 --- a/packages/adapters/web-wechat/src/index.ts +++ b/packages/adapters/web-wechat/src/index.ts @@ -48,8 +48,6 @@ const startBots = (configs: Adapter.BotConfig<'web-wechat'>[]) => { } }; const messageHandler = (bot: WechatClient, event: DingMsgEvent) => { - const master = wechatAdapter.botConfig(bot.unique_id)?.master; - const admins = wechatAdapter.botConfig(bot.unique_id)?.admins; const message = Message.from(wechatAdapter, bot, { channel: `${event.message_type}:${event instanceof PrivateMessageEvent ? event.user_id : event.group_id}`, message_id: event.message_id, @@ -57,10 +55,7 @@ const messageHandler = (bot: WechatClient, event: DingMsgEvent) => { message_type: event.message_type, sender: { ...event.sender, - permissions: [ - master && event.sender.user_id === master && 'master', - admins && admins.includes(event.sender.user_id) && 'admins', - ].filter(Boolean) as string[], + permissions: [], }, }); wechatAdapter.app!.emit('message', wechatAdapter, bot, message); diff --git a/test/.npmrc b/test/.npmrc index 8a51b002..efe53579 100644 --- a/test/.npmrc +++ b/test/.npmrc @@ -1,3 +1,4 @@ //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN} @icqqjs:registry=https://npm.pkg.github.com registry = https://registry.npmmirror.com +prefer-online=true diff --git a/zhin/src/plugins/processAdapter.ts b/zhin/src/plugins/processAdapter.ts index 2a9e329f..401a9608 100644 --- a/zhin/src/plugins/processAdapter.ts +++ b/zhin/src/plugins/processAdapter.ts @@ -4,37 +4,33 @@ import { registerAdapter, defineMetadata } from './setup'; defineMetadata({ name: `process adapter` }); const processAdapter = registerAdapter('process'); export class ProcessBot extends Adapter.BaseBot<'process'> { - constructor(config: Adapter.BotConfig<'process'>) { - process.title = config.title || 'process'; - super(processAdapter, config.unique_id, process); + constructor() { + super(processAdapter, `${process.pid}`, process); } - async handleSendMessage(channel: Message.Channel, message: string, source: Message<'process'> | undefined) { + async handleSendMessage(channel: Message.Channel, message: string) { processAdapter.logger.info(`send [${channel}]: ${unescape(message)}`); return `${Date.now()}`; } } -export interface ProcessBot extends NodeJS.Process {} -processAdapter.on('start', (configs: Adapter.BotConfig<'process'>[]) => { - for (const config of configs) { - const bot = new ProcessBot(config); - bot.stdin.on('data', (event: Buffer) => { - const message = Message.from(processAdapter, bot, { - message_id: `${Date.now()}`, - channel: `private:${bot.title}`, - sender: { - user_id: 'developer', - user_name: bot.title, - permissions: ['admin', 'master', 'normal'], - }, - raw_message: event.toString().trimEnd(), - message_type: 'private', - }); - processAdapter.logger.info(`recv [${message.channel}]: ${message.raw_message}`); - processAdapter.app!.emit('message', processAdapter, bot, message); +processAdapter.on('start', () => { + const bot = new ProcessBot() as Adapter.Bot<'process'>; + bot.stdin.on('data', (event: Buffer) => { + const message = Message.from(processAdapter, bot, { + message_id: `${Date.now()}`, + channel: `private:${bot.pid}`, + sender: { + user_id: 'developer', + user_name: bot.title, + permissions: ['admin', 'master', 'normal'], + }, + raw_message: event.toString().trimEnd(), + message_type: 'private', }); - setTimeout(() => { - processAdapter.emit('bot-ready', bot); - }, 100); - processAdapter.bots.push(bot); - } + processAdapter.logger.info(`recv [${message.channel}]: ${message.raw_message}`); + processAdapter.app!.emit('message', processAdapter, bot, message); + }); + setTimeout(() => { + processAdapter.emit('bot-ready', bot); + }, 100); + processAdapter.bots.push(bot); });