UNPKG

xinc

Version:

基于napcat,node-napcat-ts的bot框架

318 lines 15.6 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _NCWebsocketBase_instances, _NCWebsocketBase_debug, _NCWebsocketBase_baseUrl, _NCWebsocketBase_accessToken, _NCWebsocketBase_throwPromise, _NCWebsocketBase_reconnection, _NCWebsocketBase_socket, _NCWebsocketBase_eventBus, _NCWebsocketBase_echoMap, _NCWebsocketBase_message; Object.defineProperty(exports, "__esModule", { value: true }); exports.NCWebsocketBase = void 0; const ws_1 = __importDefault(require("ws")); const nanoid_1 = require("nanoid"); const NCEventBus_1 = require("./NCEventBus"); const Utils_1 = require("./Utils"); class NCWebsocketBase { constructor(NCWebsocketOptions, debug = false) { _NCWebsocketBase_instances.add(this); _NCWebsocketBase_debug.set(this, void 0); _NCWebsocketBase_baseUrl.set(this, void 0); _NCWebsocketBase_accessToken.set(this, void 0); _NCWebsocketBase_throwPromise.set(this, void 0); _NCWebsocketBase_reconnection.set(this, void 0); _NCWebsocketBase_socket.set(this, void 0); _NCWebsocketBase_eventBus.set(this, void 0); _NCWebsocketBase_echoMap.set(this, void 0); __classPrivateFieldSet(this, _NCWebsocketBase_accessToken, NCWebsocketOptions.accessToken ?? '', "f"); __classPrivateFieldSet(this, _NCWebsocketBase_throwPromise, NCWebsocketOptions.throwPromise ?? false, "f"); if ('baseUrl' in NCWebsocketOptions) { __classPrivateFieldSet(this, _NCWebsocketBase_baseUrl, NCWebsocketOptions.baseUrl, "f"); } else if ('protocol' in NCWebsocketOptions && 'host' in NCWebsocketOptions && 'port' in NCWebsocketOptions) { const { protocol, host, port } = NCWebsocketOptions; __classPrivateFieldSet(this, _NCWebsocketBase_baseUrl, protocol + '://' + host + ':' + port, "f"); } else { throw new Error('NCWebsocketOptions must contain either "protocol && host && port" or "baseUrl"'); } // 整理重连参数 const { enable = true, attempts = 10, delay = 5000 } = NCWebsocketOptions.reconnection ?? {}; __classPrivateFieldSet(this, _NCWebsocketBase_reconnection, { enable, attempts, delay, nowAttempts: 1 }, "f"); __classPrivateFieldSet(this, _NCWebsocketBase_debug, debug, "f"); __classPrivateFieldSet(this, _NCWebsocketBase_eventBus, new NCEventBus_1.NCEventBus(this), "f"); __classPrivateFieldSet(this, _NCWebsocketBase_echoMap, new Map(), "f"); } // ==================WebSocket操作============================= /** * await connect() 等待 ws 连接 */ async connect() { return new Promise((resolve, reject) => { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('socket.connecting', { reconnection: __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f") }); const socket = new ws_1.default(`${__classPrivateFieldGet(this, _NCWebsocketBase_baseUrl, "f")}?access_token=${__classPrivateFieldGet(this, _NCWebsocketBase_accessToken, "f")}`); socket.onopen = () => { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('socket.open', { reconnection: __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f") }); __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").nowAttempts = 1; resolve(); }; socket.onclose = async (event) => { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('socket.close', { code: event.code, reason: event.reason, reconnection: __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f"), }); if (__classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").enable && __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").nowAttempts < __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").attempts) { __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").nowAttempts++; setTimeout(async () => { try { await this.reconnect(); } catch (error) { reject(error); } }, __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").delay); } }; socket.onmessage = (event) => __classPrivateFieldGet(this, _NCWebsocketBase_instances, "m", _NCWebsocketBase_message).call(this, event.data); socket.onerror = (event) => { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('socket.error', { reconnection: __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f"), error_type: 'connect_error', errors: event?.error?.errors ?? [event?.error ?? null], }); if (__classPrivateFieldGet(this, _NCWebsocketBase_throwPromise, "f")) { if (__classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").enable && __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").nowAttempts < __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").attempts) { // 重连未到最后一次,等待继续重连,不抛出错误 return; } reject({ reconnection: __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f"), error_type: 'connect_error', errors: event?.error?.errors ?? [event?.error ?? null], }); } }; __classPrivateFieldSet(this, _NCWebsocketBase_socket, socket, "f"); }); } disconnect() { if (__classPrivateFieldGet(this, _NCWebsocketBase_socket, "f")) { __classPrivateFieldGet(this, _NCWebsocketBase_socket, "f").close(1000); __classPrivateFieldSet(this, _NCWebsocketBase_socket, undefined, "f"); } } async reconnect() { this.disconnect(); await this.connect(); } // ==================事件绑定============================= /** * 发送API请求 * @param method API 端点 * @param params 请求参数 */ send(method, params) { const echo = (0, nanoid_1.nanoid)(); const message = { action: method, params: params, echo, }; if (__classPrivateFieldGet(this, _NCWebsocketBase_debug, "f")) { Utils_1.logger.debug('[node-open-napcat] send request'); Utils_1.logger.dir(message); } return new Promise((resolve, reject) => { const onSuccess = (response) => { __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").delete(echo); return resolve(response.data); }; const onFailure = (reason) => { __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").delete(echo); return reject(reason); }; __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").set(echo, { message, onSuccess, onFailure, }); __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('api.preSend', message); if (__classPrivateFieldGet(this, _NCWebsocketBase_socket, "f") === undefined) { reject({ status: 'failed', retcode: -1, data: null, message: 'api socket is not connected', echo: '', }); } else if (__classPrivateFieldGet(this, _NCWebsocketBase_socket, "f").readyState === ws_1.default.CLOSING) { reject({ status: 'failed', retcode: -1, data: null, message: 'api socket is closed', echo: '', }); } else { __classPrivateFieldGet(this, _NCWebsocketBase_socket, "f").send(JSON.stringify(message)); } }); } /** * 发送API请求并返回完整响应 * @param method API 端点 * @param params 请求参数 */ call(method, params) { const echo = (0, nanoid_1.nanoid)(); const message = { action: method, params: params, echo, }; if (__classPrivateFieldGet(this, _NCWebsocketBase_debug, "f")) { Utils_1.logger.debug('[node-open-napcat] send request'); Utils_1.logger.dir(message); } return new Promise((resolve, reject) => { const onSuccess = (response) => { __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").delete(echo); return resolve(response); // 返回完整响应 }; const onFailure = (reason) => { __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").delete(echo); return resolve(reason); // 失败时也返回响应而不是reject }; __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").set(echo, { message, onSuccess, onFailure, }); __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('api.preSend', message); if (__classPrivateFieldGet(this, _NCWebsocketBase_socket, "f") === undefined) { reject({ status: 'failed', retcode: -1, data: null, message: 'api socket is not connected', echo: '', }); } else if (__classPrivateFieldGet(this, _NCWebsocketBase_socket, "f").readyState === ws_1.default.CLOSING) { reject({ status: 'failed', retcode: -1, data: null, message: 'api socket is closed', echo: '', }); } else { __classPrivateFieldGet(this, _NCWebsocketBase_socket, "f").send(JSON.stringify(message)); } }); } /** * 注册监听方法 * @param event * @param handle */ on(event, handle) { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").on(event, handle); return this; } /** * 只执行一次 * @param event * @param handle */ once(event, handle) { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").once(event, handle); return this; } /** * 解除监听方法 * @param event * @param handle */ off(event, handle) { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").off(event, handle); return this; } /** * 手动模拟触发某个事件 * @param type * @param context */ emit(type, context) { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit(type, context); return this; } } exports.NCWebsocketBase = NCWebsocketBase; _NCWebsocketBase_debug = new WeakMap(), _NCWebsocketBase_baseUrl = new WeakMap(), _NCWebsocketBase_accessToken = new WeakMap(), _NCWebsocketBase_throwPromise = new WeakMap(), _NCWebsocketBase_reconnection = new WeakMap(), _NCWebsocketBase_socket = new WeakMap(), _NCWebsocketBase_eventBus = new WeakMap(), _NCWebsocketBase_echoMap = new WeakMap(), _NCWebsocketBase_instances = new WeakSet(), _NCWebsocketBase_message = function _NCWebsocketBase_message(data) { let json; try { json = JSON.parse(data.toString()); if (json.post_type === 'message' || json.post_type === 'message_sent') { if (json.message_format === 'string') { json = JSON.parse((0, Utils_1.CQCodeDecode)(json)); json.message = (0, Utils_1.convertCQCodeToJSON)(json.message); json.message_format = 'array'; } json.raw_message = (0, Utils_1.CQCodeDecode)(json.raw_message); } } catch (error) { Utils_1.logger.warn('[node-napcat-ts]', '[socket]', 'failed to parse JSON'); Utils_1.logger.dir(error); return; } if (__classPrivateFieldGet(this, _NCWebsocketBase_debug, "f")) { Utils_1.logger.debug('[node-napcat-ts]', '[socket]', 'receive data'); Utils_1.logger.dir(json); } if (json.echo) { const handler = __classPrivateFieldGet(this, _NCWebsocketBase_echoMap, "f").get(json.echo); if (handler) { if (json.retcode === 0) { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('api.response.success', json); handler.onSuccess(json); } else { __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('api.response.failure', json); handler.onFailure(json); } } } else { if (json?.status === 'failed' && json?.echo === null) { __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f").enable = false; __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").emit('socket.error', { reconnection: __classPrivateFieldGet(this, _NCWebsocketBase_reconnection, "f"), error_type: 'response_error', info: { url: __classPrivateFieldGet(this, _NCWebsocketBase_baseUrl, "f"), errno: json.retcode, message: json.message, }, }); if (__classPrivateFieldGet(this, _NCWebsocketBase_throwPromise, "f")) throw new Error(json.message); this.disconnect(); return; } __classPrivateFieldGet(this, _NCWebsocketBase_eventBus, "f").parseMessage(json); } }; //# sourceMappingURL=NCWebsocketBase.js.map