onebots
Version:
基于icqq的多例oneBot实现
318 lines (317 loc) • 13 kB
JavaScript
;
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;