UNPKG

onebots

Version:

基于icqq的多例oneBot实现

318 lines (317 loc) 13 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; 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 _QQAdapter_disposes; Object.defineProperty(exports, "__esModule", { value: true }); const adapter_1 = require("../../adapter"); const onebot_1 = require("../../onebot"); const qq_official_bot_1 = require("qq-official-bot"); const path = __importStar(require("path")); class QQAdapter extends adapter_1.Adapter { constructor(app, config) { super(app, "qq", config); _QQAdapter_disposes.set(this, new Map()); this.icon = `https://qzonestyle.gtimg.cn/qzone/qzact/act/external/tiqq/logo.png`; } async startOneBot(oneBot) { await this.setOnline(oneBot.uin); const selfInfo = await oneBot.internal.getSelfInfo(); oneBot.avatar = selfInfo.avatar; oneBot.nickname = selfInfo.username; const pkg = require(path.resolve(path.dirname(require.resolve("qq-official-bot")), "../package.json")); oneBot.dependency = `qq-official-bot v${pkg.version}`; const disposeArr = []; const clean = () => { while (disposeArr.length > 0) { disposeArr.pop()(); } oneBot.internal.stop(); }; const messageHandler = event => { this.emit("message.receive", oneBot.uin, event); }; oneBot.internal.on("message", messageHandler); disposeArr.push(() => { oneBot.internal.off("message", messageHandler); }); return clean; } async setOnline(uin) { const oneBot = this.getOneBot(uin); await oneBot?.internal.start(); oneBot.status = onebot_1.OneBotStatus.Online; } async setOffline(uin) { const oneBot = this.getOneBot(uin); await oneBot?.internal.stop(); oneBot.status = onebot_1.OneBotStatus.OffLine; } createOneBot(uin, protocol, versions) { const oneBot = super.createOneBot(uin, protocol, versions); oneBot.internal = new qq_official_bot_1.Bot({ appid: oneBot.uin, logLevel: this.app.config.log_level, ...protocol, }); oneBot.status = onebot_1.OneBotStatus.Pending; return oneBot; } async sendGroupMessage(uin, version, args) { let [group_id, message, source] = args; if (version === "V11") { const [sub_type] = group_id.split(":"); if (sub_type === "guild") { const [guild_id, channel_id] = group_id.slice(6); return await this.sendGuildMessage(uin, version, [ group_id, channel_id, message, source, ]); } } const bot = this.getOneBot(uin); let quote; if (source) quote = { id: source }; const result = await bot.internal.sendGroupMessage(group_id, message, quote); return { message_id: version === "V11" ? bot.V11.transformToInt("message_id", `group:${group_id}${result["id"] || result["file_uuid"]}`) : `group:${group_id}${result["id"] || result["file_uuid"]}`, }; } async sendPrivateMessage(uin, version, args) { let [user_id, message, source] = args; if (version === "V11") { const [sub_type, real_user_id = sub_type] = user_id.split(":"); if (sub_type === "direct") return await this.sendDirectMessage(uin, version, [ user_id.slice(7), message, source, ]); user_id = real_user_id; } const bot = this.getOneBot(uin); let quote; if (source) quote = { id: source }; const result = await bot.internal.sendPrivateMessage(user_id, message, quote); return { message_id: version === "V11" ? bot.V11.transformToInt("message_id", `private:${user_id}${result["id"] || result["file_uuid"]}`) : `private:${user_id}${result["id"] || result["file_uuid"]}`, }; } async sendGuildMessage(uin, version, args) { const [guild_id, channel_id, message, source] = args; const bot = this.getOneBot(uin); let quote; if (source) quote = { id: source }; const result = await bot.internal.sendGuildMessage(channel_id, message, quote); return { message_id: version === "V11" ? bot.V11.transformToInt("message_id", `${guild_id}:${channel_id}${result["id"] || result["file_uuid"]}`) : `${guild_id}:${channel_id}${result["id"] || result["file_uuid"]}`, }; } async sendDirectMessage(uin, version, args) { const [guild_id, message, source] = args; const bot = this.getOneBot(uin); let quote; if (source) quote = { id: source }; const result = await bot.internal.sendDirectMessage(guild_id, message, quote); return { message_id: version === "V11" ? bot.V11.transformToInt("message_id", `direct:${guild_id}${result["id"] || result["file_uuid"]}`) : `direct:${guild_id}${result["id"] || result["file_uuid"]}`, }; } async deleteMessage(uin, version, [message_id]) { const [from_type, from_id, ...msg_idArr] = message_id.split(":"); const bot = this.getOneBot(uin).internal; if (version === "V11") { const [sub_type, real_user_id = sub_type] = from_id.split(":"); if (sub_type === "direct") return await bot.recallDirectMessage(from_id.slice(7), message_id); } switch (from_type) { case "private": return bot.recallPrivateMessage(from_id, msg_idArr.join(":")); case "group": return bot.recallGroupMessage(from_id, msg_idArr.join(":")); case "direct": return bot.recallDirectMessage(from_id, msg_idArr.join(":")); case "guild": return bot.recallGuildMessage(from_id, msg_idArr.join(":")); } } call(uin, version, method, args) { const oneBot = this.oneBots.get(uin); if (!oneBot) { throw new Error(`未找到账号${uin}`); } if (typeof this[method] === "function") return this[method](uin, version, args); if (typeof oneBot.internal[method] !== "function") throw onebot_1.OneBot.UnsupportedMethodError; try { return oneBot.internal[method](...(args || [])); } catch (e) { throw new Error(`call internal method error:${e.message}`); } } async uploadMedia(uin, target_id, target_type, file_data, file_type) { const bot = this.getOneBot(uin).internal; return bot.uploadMedia(target_id, target_type, file_data, file_type); } fromSegment(onebot, version, segment) { return [] .concat(segment) .map(segment => { if (version === "V12" && ["image", "video", "audio"].includes(segment.type)) return onebot.V12.transformMedia(segment); if (segment.type === "reply") { if (version === "V11") segment.data.id = onebot.V11.getStrByInt("message_id", segment.data.id); const [_1, _2, ...others] = (segment.data.id || "").split(":"); segment.data.id = others.join(":"); } return segment; }) .map(item => { if (typeof item === "string") return item; const { type, data } = item; return { type, ...data, }; }); } toSegment(version, message) { return [].concat(message).map(item => { if (!item || typeof item !== "object") return { type: "text", data: { text: item, }, }; const { type, ...data } = item; return { type, data, }; }); } formatEventPayload(uin, version, event, data) { const result = { id: data.id || Math.random().toString(36).slice(2), [version === "V12" ? "type" : "post_type"]: event, version: version, self: { platform: "qq", user_id: data.self_id, }, detail_type: data.message_type || data.notice_type || data.request_type, platform: "qq", time: data.timestamp, ...data, sender: { ...(data?.sender || {}), }, user_id: data.user_id || data.sender?.user_id, }; if (result.message_id) { if (result.message_type === "private") { result.message_id = `${result.sub_type}:${result.guild_id || result.group_id || result.user_id}:${result.message_id}`; result.user_id = `${result.sub_type}:${result.guild_id || result.group_id || result.user_id}`; if (result.sender) result.sender.user_id = result.user_id; } else if (result.message_type === "guild") { result.message_type = "group"; result.message_id = `guild:${result.guild_id}:${result.channel_id}:${result.message_id}`; result.group_id = `guild:${result.guild_id}:${result.channel_id}`; } else { result.message_id = `${result.message_type}:${result.channel_id || result.guild_id || result.group_id || result.user_id}:${result.message_id}`; } } delete result.bot; const oneBot = this.getOneBot(uin); if (event === "message") { result.alt_message = result.raw_message || ""; } switch (version) { case "V11": oneBot.V11.transformStrToIntForObj(result, ["message_id", "user_id", "group_id"]); oneBot.V11.transformStrToIntForObj(result.sender, ["user_id"]); oneBot.V11.transformStrToIntForObj(result.self, ["user_id"]); break; } return result; } async start(uin) { const startOneBots = [...this.oneBots.values()].filter(oneBot => { return uin ? oneBot.uin === uin : true; }); for (const oneBot of startOneBots) { __classPrivateFieldGet(this, _QQAdapter_disposes, "f").set(oneBot.uin, await this.startOneBot(oneBot)); } const { protocol } = this.config; await super.start(); } async stop(uin) { const stopOneBots = [...this.oneBots.values()].filter(oneBot => { return uin ? oneBot.uin === uin : true; }); for (const oneBot of stopOneBots) { const dispose = __classPrivateFieldGet(this, _QQAdapter_disposes, "f").get(oneBot.uin); if (dispose) { dispose(); } } await super.stop(); } getSelfInfo(uin, version) { const oneBot = this.oneBots.get(uin); return { nickname: oneBot?.internal?.nickname, status: onebot_1.OneBotStatus.Online, }; } } _QQAdapter_disposes = new WeakMap(); exports.default = QQAdapter;