diff --git a/packages/napcat-satori/action/SatoriAction.ts b/packages/napcat-satori/action/SatoriAction.ts index bb48ae92..f0fb7f8f 100644 --- a/packages/napcat-satori/action/SatoriAction.ts +++ b/packages/napcat-satori/action/SatoriAction.ts @@ -1,5 +1,5 @@ import { NapCatCore } from 'napcat-core'; -import { NapCatSatoriAdapter } from '@/napcat-satori/index'; +import { NapCatSatoriAdapter } from '../index'; export abstract class SatoriAction { abstract actionName: string; diff --git a/packages/napcat-satori/action/channel/ChannelGet.ts b/packages/napcat-satori/action/channel/ChannelGet.ts index 046d4ff4..c88049e6 100644 --- a/packages/napcat-satori/action/channel/ChannelGet.ts +++ b/packages/napcat-satori/action/channel/ChannelGet.ts @@ -1,5 +1,5 @@ import { SatoriAction } from '../SatoriAction'; -import { SatoriChannel, SatoriChannelType } from '@/napcat-satori/types'; +import { SatoriChannel, SatoriChannelType } from '../../types'; interface ChannelGetPayload { channel_id: string; diff --git a/packages/napcat-satori/action/channel/ChannelList.ts b/packages/napcat-satori/action/channel/ChannelList.ts index abd08ee8..55f47d56 100644 --- a/packages/napcat-satori/action/channel/ChannelList.ts +++ b/packages/napcat-satori/action/channel/ChannelList.ts @@ -1,5 +1,5 @@ import { SatoriAction } from '../SatoriAction'; -import { SatoriChannel, SatoriChannelType, SatoriPageResult } from '@/napcat-satori/types'; +import { SatoriChannel, SatoriChannelType, SatoriPageResult } from '../../types'; interface ChannelListPayload { guild_id: string; diff --git a/packages/napcat-satori/action/guild/GuildGet.ts b/packages/napcat-satori/action/guild/GuildGet.ts index cfe3b73b..d254902c 100644 --- a/packages/napcat-satori/action/guild/GuildGet.ts +++ b/packages/napcat-satori/action/guild/GuildGet.ts @@ -1,5 +1,5 @@ import { SatoriAction } from '../SatoriAction'; -import { SatoriGuild } from '@/napcat-satori/types'; +import { SatoriGuild } from '../../types'; interface GuildGetPayload { guild_id: string; diff --git a/packages/napcat-satori/action/guild/GuildList.ts b/packages/napcat-satori/action/guild/GuildList.ts index d0d29522..5b5bc20e 100644 --- a/packages/napcat-satori/action/guild/GuildList.ts +++ b/packages/napcat-satori/action/guild/GuildList.ts @@ -1,5 +1,5 @@ import { SatoriAction } from '../SatoriAction'; -import { SatoriGuild, SatoriPageResult } from '@/napcat-satori/types'; +import { SatoriGuild, SatoriPageResult } from '../../types'; interface GuildListPayload { next?: string; diff --git a/packages/napcat-satori/action/guild/GuildMemberGet.ts b/packages/napcat-satori/action/guild/GuildMemberGet.ts index d30928af..07616fa8 100644 --- a/packages/napcat-satori/action/guild/GuildMemberGet.ts +++ b/packages/napcat-satori/action/guild/GuildMemberGet.ts @@ -1,5 +1,5 @@ import { SatoriAction } from '../SatoriAction'; -import { SatoriGuildMember } from '@/napcat-satori/types'; +import { SatoriGuildMember } from '../../types'; interface GuildMemberGetPayload { guild_id: string; @@ -25,7 +25,7 @@ export class GuildMemberGetAction extends SatoriAction { const { channel_id, message_id } = payload; - const [type, id] = channel_id.split(':'); + const parts = channel_id.split(':'); + const type = parts[0]; + const id = parts[1]; + + if (!type || !id) { + throw new Error(`无效的频道ID: ${channel_id}`); + } let chatType: ChatType; let peerUid: string; @@ -36,6 +42,10 @@ export class MessageGetAction extends SatoriAction { + const prev = this.configLoader.configData; + this.configLoader.save(newConfig); + await this.reloadNetwork(prev, newConfig); + }); } async reloadNetwork (prev: SatoriConfig, now: SatoriConfig): Promise { diff --git a/packages/napcat-satori/network/adapter.ts b/packages/napcat-satori/network/adapter.ts index 3ed11016..cfd7c7e3 100644 --- a/packages/napcat-satori/network/adapter.ts +++ b/packages/napcat-satori/network/adapter.ts @@ -1,9 +1,9 @@ -import { SatoriNetworkAdapterConfig } from '@/napcat-satori/config/config'; +import { SatoriNetworkAdapterConfig } from '../config/config'; import { LogWrapper } from 'napcat-core/helper/log'; import { NapCatCore } from 'napcat-core'; -import { NapCatSatoriAdapter } from '@/napcat-satori/index'; -import { SatoriActionMap } from '@/napcat-satori/action'; -import { SatoriEvent } from '@/napcat-satori/types'; +import { NapCatSatoriAdapter } from '../index'; +import { SatoriActionMap } from '../action'; +import { SatoriEvent } from '../types'; export enum SatoriNetworkReloadType { Normal = 0, diff --git a/packages/napcat-satori/network/http-server.ts b/packages/napcat-satori/network/http-server.ts index 2a553199..6b219608 100644 --- a/packages/napcat-satori/network/http-server.ts +++ b/packages/napcat-satori/network/http-server.ts @@ -1,15 +1,15 @@ import express, { Express, Request, Response, NextFunction } from 'express'; import { createServer, Server } from 'http'; import { NapCatCore } from 'napcat-core'; -import { NapCatSatoriAdapter } from '@/napcat-satori/index'; -import { SatoriActionMap } from '@/napcat-satori/action'; -import { SatoriHttpServerConfig } from '@/napcat-satori/config/config'; +import { NapCatSatoriAdapter } from '../index'; +import { SatoriActionMap } from '../action'; +import { SatoriHttpServerConfig } from '../config/config'; import { ISatoriNetworkAdapter, SatoriEmitEventContent, SatoriNetworkReloadType, } from './adapter'; -import { SatoriApiResponse, SatoriLoginStatus } from '@/napcat-satori/types'; +import { SatoriApiResponse, SatoriLoginStatus } from '../types'; export class SatoriHttpServerAdapter extends ISatoriNetworkAdapter { private app: Express | null = null; diff --git a/packages/napcat-satori/network/index.ts b/packages/napcat-satori/network/index.ts index fab2e430..108091e5 100644 --- a/packages/napcat-satori/network/index.ts +++ b/packages/napcat-satori/network/index.ts @@ -1,5 +1,5 @@ -import { ISatoriNetworkAdapter, SatoriEmitEventContent, SatoriNetworkReloadType } from './adapter'; -import { SatoriNetworkAdapterConfig } from '@/napcat-satori/config/config'; +import { ISatoriNetworkAdapter, SatoriEmitEventContent } from './adapter'; +import { SatoriNetworkAdapterConfig } from '../config/config'; export class SatoriNetworkManager { adapters: Map> = new Map(); @@ -23,7 +23,7 @@ export class SatoriNetworkManager { async openAllAdapters (): Promise { const openPromises = Array.from(this.adapters.values()).map((adapter) => - adapter.open().catch((e) => { + Promise.resolve(adapter.open()).catch((e) => { adapter.logger.logError(`[Satori] 适配器 ${adapter.name} 启动失败: ${e}`); }) ); @@ -32,7 +32,7 @@ export class SatoriNetworkManager { async closeAllAdapters (): Promise { const closePromises = Array.from(this.adapters.values()).map((adapter) => - adapter.close().catch((e) => { + Promise.resolve(adapter.close()).catch((e) => { adapter.logger.logError(`[Satori] 适配器 ${adapter.name} 关闭失败: ${e}`); }) ); diff --git a/packages/napcat-satori/network/webhook-client.ts b/packages/napcat-satori/network/webhook-client.ts index 8fac72b5..213e77e0 100644 --- a/packages/napcat-satori/network/webhook-client.ts +++ b/packages/napcat-satori/network/webhook-client.ts @@ -1,7 +1,7 @@ import { NapCatCore } from 'napcat-core'; -import { NapCatSatoriAdapter } from '@/napcat-satori/index'; -import { SatoriActionMap } from '@/napcat-satori/action'; -import { SatoriWebHookClientConfig } from '@/napcat-satori/config/config'; +import { NapCatSatoriAdapter } from '../index'; +import { SatoriActionMap } from '../action'; +import { SatoriWebHookClientConfig } from '../config/config'; import { ISatoriNetworkAdapter, SatoriEmitEventContent, diff --git a/packages/napcat-satori/network/websocket-server.ts b/packages/napcat-satori/network/websocket-server.ts index 28630f0d..9af00ba7 100644 --- a/packages/napcat-satori/network/websocket-server.ts +++ b/packages/napcat-satori/network/websocket-server.ts @@ -1,9 +1,9 @@ import { WebSocketServer, WebSocket } from 'ws'; import { createServer, Server, IncomingMessage } from 'http'; import { NapCatCore } from 'napcat-core'; -import { NapCatSatoriAdapter } from '@/napcat-satori/index'; -import { SatoriActionMap } from '@/napcat-satori/action'; -import { SatoriWebSocketServerConfig } from '@/napcat-satori/config/config'; +import { NapCatSatoriAdapter } from '../index'; +import { SatoriActionMap } from '../action'; +import { SatoriWebSocketServerConfig } from '../config/config'; import { ISatoriNetworkAdapter, SatoriEmitEventContent, @@ -15,7 +15,7 @@ import { SatoriIdentifyBody, SatoriReadyBody, SatoriLoginStatus, -} from '@/napcat-satori/types'; +} from '../types'; interface ClientInfo { ws: WebSocket; diff --git a/packages/napcat-webui-backend/src/api/ProtocolConfig.ts b/packages/napcat-webui-backend/src/api/ProtocolConfig.ts index f530dacb..76755012 100644 --- a/packages/napcat-webui-backend/src/api/ProtocolConfig.ts +++ b/packages/napcat-webui-backend/src/api/ProtocolConfig.ts @@ -104,6 +104,78 @@ export const SatoriSetConfigHandler: RequestHandler = async (req, res) => { } }; +// 获取指定协议配置 +export const GetProtocolConfigHandler: RequestHandler = (req, res) => { + const isLogin = WebUiDataRuntime.getQQLoginStatus(); + if (!isLogin) { + return sendError(res, 'Not Login'); + } + + const { name } = req.params; + const uin = WebUiDataRuntime.getQQLoginUin(); + // 映射 protocol name 到文件名 + const protocolId = name === 'onebot11' ? 'onebot11' : name; + + const configFilePath = resolve(webUiPathWrapper.configPath, `./${protocolId}_${uin}.json`); + + try { + let configData: any = {}; + // Satori 特殊处理默认值, 其他协议也可以在这里添加默认值 + if (name === 'satori') { + configData = { + network: { + websocketServers: [], + httpServers: [], + webhookClients: [], + }, + platform: 'qq', + selfId: uin, + }; + } + + if (existsSync(configFilePath)) { + const content = readFileSync(configFilePath, 'utf-8'); + configData = json5.parse(content); + } + return sendSuccess(res, configData); + } catch (e) { + return sendError(res, 'Config Get Error: ' + e); + } +}; + +// 设置指定协议配置 +export const SetProtocolConfigHandler: RequestHandler = async (req, res) => { + const isLogin = WebUiDataRuntime.getQQLoginStatus(); + if (!isLogin) { + return sendError(res, 'Not Login'); + } + + const { name } = req.params; + if (isEmpty(req.body.config)) { + return sendError(res, 'config is empty'); + } + + try { + const config = json5.parse(req.body.config); + if (name === 'satori') { + await WebUiDataRuntime.setSatoriConfig(config); + } else { + // 对于未特殊处理的协议,走通用的写文件逻辑 + const uin = WebUiDataRuntime.getQQLoginUin(); + // TODO: 这里目前 napcat-core 及其 helper 可能没有通用的 setConfig, + // 但 WebUiDataRuntime.setSatoriConfig 本质也是写文件。 + // 暂时只支持 Satori 的通用调用 via this handler, + // OneBot11 还是走原来的 /api/config + if (name !== 'satori') { + return sendError(res, 'Protocol not supported for generic set yet'); + } + } + return sendSuccess(res, null); + } catch (e) { + return sendError(res, 'Error: ' + e); + } +}; + // 获取所有协议配置 export const GetAllProtocolConfigsHandler: RequestHandler = (_req, res) => { const isLogin = WebUiDataRuntime.getQQLoginStatus(); diff --git a/packages/napcat-webui-backend/src/router/ProtocolConfig.ts b/packages/napcat-webui-backend/src/router/ProtocolConfig.ts index 7acf52b2..1f828ed2 100644 --- a/packages/napcat-webui-backend/src/router/ProtocolConfig.ts +++ b/packages/napcat-webui-backend/src/router/ProtocolConfig.ts @@ -5,6 +5,8 @@ import { SatoriGetConfigHandler, SatoriSetConfigHandler, GetAllProtocolConfigsHandler, + GetProtocolConfigHandler, + SetProtocolConfigHandler, } from '@/napcat-webui-backend/src/api/ProtocolConfig'; const router = Router(); @@ -18,8 +20,12 @@ router.get('/status', GetProtocolStatusHandler); // 获取所有协议配置 router.get('/all', GetAllProtocolConfigsHandler); -// Satori 配置 +// Satori 配置 (Reserved for backward compatibility or specific usage) router.get('/satori', SatoriGetConfigHandler); router.post('/satori', SatoriSetConfigHandler); +// 通用协议配置路由 +router.get('/:name/config', GetProtocolConfigHandler); +router.post('/:name/config', SetProtocolConfigHandler); + export { router as ProtocolConfigRouter };