refactor: forwardPairs 跟随 instance 实例化

This commit is contained in:
Clansty 2022-03-07 18:05:14 +08:00
parent 315a2cd544
commit c909dcca44
No known key found for this signature in database
GPG Key ID: 05F8479BA63A8E92
10 changed files with 87 additions and 61 deletions

View File

@ -15,7 +15,7 @@ interface CreateOicqParams {
uin: number;
password: string;
platform: Platform;
// 当需要验证手机时调用此方法,应该返回收到手机验证码
// 当需要验证手机时调用此方法,应该返回收到手机验证码
onVerifyDevice: (phone: string) => Promise<string>;
// 当滑块时调用此方法,返回 ticker也可以返回假值改用扫码登录
onVerifySlider: (url: string) => Promise<string>;

View File

@ -3,7 +3,6 @@ import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import ConfigService from '../services/ConfigService';
import regExps from '../constants/regExps';
import forwardPairs from '../models/forwardPairs';
import { GroupMessageEvent, MemberIncreaseEvent, PrivateMessageEvent } from 'oicq';
import Instance from '../models/Instance';
@ -73,7 +72,7 @@ export default class ConfigController {
private handleServiceMessage = async (message: Api.MessageService) => {
// 用于检测群升级为超级群的情况
if (message.action instanceof Api.MessageActionChatMigrateTo) {
const pair = forwardPairs.find((message.peerId as Api.PeerChat).chatId);
const pair = this.instance.forwardPairs.find((message.peerId as Api.PeerChat).chatId);
if (!pair) return;
// 会自动写入数据库
pair.tg = await this.tgBot.getChat(message.action.channelId);
@ -93,7 +92,7 @@ export default class ConfigController {
private handleQqMessage = async (message: GroupMessageEvent | PrivateMessageEvent) => {
if (message.message_type !== 'private') return false;
const pair = forwardPairs.find(message.friend);
const pair = this.instance.forwardPairs.find(message.friend);
if (pair) return false;
// 如果正在创建中,应该阻塞
let promise = this.createPrivateMessageGroupBlockList.get(message.from_id);
@ -109,7 +108,7 @@ export default class ConfigController {
};
private handleMemberIncrease = async (event: MemberIncreaseEvent) => {
if (event.user_id !== this.oicq.uin || await forwardPairs.find(event.group)) return;
if (event.user_id !== this.oicq.uin || await this.instance.forwardPairs.find(event.group)) return;
// 是新群并且是自己加入了
await this.configService.promptNewGroup(event.group);
};

View File

@ -3,7 +3,6 @@ import { getLogger } from 'log4js';
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import { Api } from 'telegram';
import forwardPairs from '../models/forwardPairs';
import { FriendRecallEvent, GroupRecallEvent } from 'oicq';
import { DeletedMessageEvent } from 'telegram/events/DeletedMessage';
import Instance from '../models/Instance';
@ -25,7 +24,7 @@ export default class DeleteMessageController {
}
private onTelegramMessage = async (message: Api.Message) => {
const pair = forwardPairs.find(message.chat);
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return false;
// TODO: 可以做成 DeleteMessageController 之类
if (message.message?.startsWith('/rm')) {
@ -36,25 +35,25 @@ export default class DeleteMessageController {
};
private onTelegramEditMessage = async (message: Api.Message) => {
const pair = forwardPairs.find(message.chat);
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return;
await this.deleteMessageService.telegramDeleteMessage(message.id, pair);
return await this.onTelegramMessage(message);
};
private onQqFriendRecall = async (event: FriendRecallEvent) => {
const pair = forwardPairs.find(event.friend);
const pair = this.instance.forwardPairs.find(event.friend);
await this.deleteMessageService.handleQqRecall(event, pair);
};
private onQqGroupRecall = async (event: GroupRecallEvent) => {
const pair = forwardPairs.find(event.group);
const pair = this.instance.forwardPairs.find(event.group);
await this.deleteMessageService.handleQqRecall(event, pair);
};
private onTgDeletedMessage = async (event: DeletedMessageEvent) => {
if (!(event.peer instanceof Api.PeerChannel)) return;
const pair = forwardPairs.find(event.peer.channelId);
const pair = this.instance.forwardPairs.find(event.peer.channelId);
if (!pair) return;
for (const messageId of event.deletedIds) {
await this.deleteMessageService.telegramDeleteMessage(messageId, pair);

View File

@ -1,7 +1,6 @@
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import ForwardService from '../services/ForwardService';
import forwardPairs from '../models/forwardPairs';
import { GroupMessageEvent, PrivateMessageEvent } from 'oicq';
import db from '../models/db';
import { Api } from 'telegram';
@ -17,16 +16,15 @@ export default class ForwardController {
private readonly tgUser: Telegram,
private readonly oicq: OicqClient) {
this.forwardService = new ForwardService(this.instance, tgBot, oicq);
forwardPairs.init(oicq, tgBot)
.then(() => oicq.addNewMessageEventHandler(this.onQqMessage))
.then(() => tgBot.addNewMessageEventHandler(this.onTelegramMessage))
.then(() => tgBot.addEditedMessageEventHandler(this.onTelegramMessage));
oicq.addNewMessageEventHandler(this.onQqMessage);
tgBot.addNewMessageEventHandler(this.onTelegramMessage);
tgBot.addEditedMessageEventHandler(this.onTelegramMessage);
}
private onQqMessage = async (event: PrivateMessageEvent | GroupMessageEvent) => {
try {
const target = event.message_type === 'private' ? event.friend : event.group;
const pair = forwardPairs.find(target);
const pair = this.instance.forwardPairs.find(target);
if (!pair) return;
const tgMessage = await this.forwardService.forwardFromQq(event, pair);
if (tgMessage) {
@ -53,7 +51,7 @@ export default class ForwardController {
private onTelegramMessage = async (message: Api.Message) => {
try {
const pair = forwardPairs.find(message.chat);
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return false;
const qqMessageSent = await this.forwardService.forwardFromTelegram(message, pair);
// 返回的信息不太够

View File

@ -4,45 +4,21 @@ import OicqClient from '../client/OicqClient';
import Telegram from '../client/Telegram';
import db from './db';
import { Entity } from 'telegram/define';
import { getLogger } from 'log4js';
import { BigInteger } from 'big-integer';
import { Pair } from './Pair';
const log = getLogger('ForwardPairs');
export class Pair {
constructor(public readonly qq: Friend | Group,
private _tg: TelegramChat,
public dbId: number) {
}
get qqRoomId() {
return this.qq instanceof Friend ? this.qq.user_id : -this.qq.group_id;
}
get tgId() {
return Number(this._tg.id);
}
get tg() {
return this._tg;
}
set tg(value: TelegramChat) {
this._tg = value;
db.forwardPair.update({
where: { id: this.dbId },
data: { tgChatId: Number(value.id) },
})
.then(() => log.info(`出现了到超级群组的转换: ${value.id}`));
}
}
class ForwardPairsInternal {
export default class ForwardPairs {
private pairs: Pair[] = [];
private constructor(private readonly instanceId: number) {
}
// 在 forwardController 创建时初始化
public async init(oicq: OicqClient, tgBot: Telegram) {
const dbValues = await db.forwardPair.findMany();
private async init(oicq: OicqClient, tgBot: Telegram) {
const dbValues = await db.forwardPair.findMany({
where: { instanceId: this.instanceId },
});
for (const i of dbValues) {
this.pairs.push(new Pair(
oicq.getChat(Number(i.qqRoomId)),
@ -52,11 +28,18 @@ class ForwardPairsInternal {
}
}
public static async load(instanceId: number, oicq: OicqClient, tgBot: Telegram) {
const instance = new this(instanceId);
await instance.init(oicq, tgBot);
return instance;
}
public async add(qq: Friend | Group, tg: TelegramChat) {
const dbEntry = await db.forwardPair.create({
data: {
qqRoomId: qq instanceof Friend ? qq.user_id : -qq.group_id,
tgChatId: Number(tg.id),
instanceId: this.instanceId,
},
});
this.pairs.push(new Pair(qq, tg, dbEntry.id));
@ -79,5 +62,3 @@ class ForwardPairsInternal {
}
}
}
export default new ForwardPairsInternal();

View File

@ -9,6 +9,7 @@ import FileAndFlashPhotoController from '../controllers/FileAndFlashPhotoControl
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import { getLogger, Logger } from 'log4js';
import ForwardPairs from './ForwardPairs';
export default class Instance {
private _owner = 0;
@ -17,9 +18,11 @@ export default class Instance {
private _qqPlatform = 0;
private _isSetup = false;
private _workMode = '';
private _botToken = '';
private readonly log: Logger;
public forwardPairs: ForwardPairs;
private setupController: SetupController;
private configController: ConfigController;
private deleteMessageController: DeleteMessageController;
@ -53,12 +56,13 @@ export default class Instance {
this._qqPlatform = dbEntry.qqPlatform;
this._isSetup = dbEntry.isSetup;
this._workMode = dbEntry.workMode;
this._botToken = dbEntry.botToken;
}
private async init() {
this.log.debug('正在登录 TG Bot');
const tgBot = await Telegram.create({
botAuthToken: process.env.TG_BOT_TOKEN,
botAuthToken: this.botToken,
}, 'bot');
let tgUser: Telegram, oicq: OicqClient;
@ -83,6 +87,7 @@ export default class Instance {
});
this.log.debug('OICQ 登录完成');
}
this.forwardPairs = await ForwardPairs.load(this.id, oicq, tgBot);
this.configController = new ConfigController(this, tgBot, tgUser, oicq);
this.deleteMessageController = new DeleteMessageController(this, tgBot, tgUser, oicq);
this.forwardController = new ForwardController(this, tgBot, tgUser, oicq);
@ -96,6 +101,13 @@ export default class Instance {
return instance;
}
public static async createNew(botToken: string) {
const dbEntry = await db.instance.create({
data: { botToken },
});
return await this.start(dbEntry.id);
}
get owner() {
return this._owner;
}
@ -120,6 +132,10 @@ export default class Instance {
return this._workMode as WorkMode;
}
get botToken() {
return this.id === 0 ? process.env.TG_BOT_TOKEN : this._botToken;
}
set owner(owner: number) {
this._owner = owner;
db.instance.update({

34
src/models/Pair.ts Normal file
View File

@ -0,0 +1,34 @@
import { Friend, Group } from 'oicq';
import TelegramChat from '../client/TelegramChat';
import db from './db';
import { getLogger } from 'log4js';
const log = getLogger('ForwardPairs');
export class Pair {
constructor(public readonly qq: Friend | Group,
private _tg: TelegramChat,
public dbId: number) {
}
get qqRoomId() {
return this.qq instanceof Friend ? this.qq.user_id : -this.qq.group_id;
}
get tgId() {
return Number(this._tg.id);
}
get tg() {
return this._tg;
}
set tg(value: TelegramChat) {
this._tg = value;
db.forwardPair.update({
where: { id: this.dbId },
data: { tgChatId: Number(value.id) },
})
.then(() => log.info(`出现了到超级群组的转换: ${value.id}`));
}
}

View File

@ -10,7 +10,6 @@ import commands from '../constants/commands';
import OicqClient from '../client/OicqClient';
import { md5 } from '../utils/hashing';
import TelegramChat from '../client/TelegramChat';
import forwardPairs from '../models/forwardPairs';
import Instance from '../models/Instance';
const DEFAULT_FILTER_ID = 114; // 514
@ -45,7 +44,7 @@ export default class ConfigService {
// 开始添加转发群组流程
public async addGroup() {
const qGroups = Array.from(this.oicq.gl).map(e => e[1])
.filter(it => !forwardPairs.find(-it.group_id));
.filter(it => !this.instance.forwardPairs.find(-it.group_id));
const buttons = qGroups.map(e =>
this.instance.workMode === 'personal' ?
[Button.inline(
@ -83,7 +82,7 @@ export default class ConfigService {
}
private async openFriendSelection(clazz: FriendInfo[], name: string) {
clazz = clazz.filter(them => !forwardPairs.find(them.user_id));
clazz = clazz.filter(them => !this.instance.forwardPairs.find(them.user_id));
await (await this.owner).createPaginatedInlineSelector(`选择 QQ 好友\n分组${name}`, clazz.map(e => [
Button.inline(`${e.remark || e.nickname} (${e.user_id})`, this.tgBot.registerCallback(
() => this.createGroupAndLink(e.user_id, e.remark || e.nickname),
@ -179,7 +178,7 @@ export default class ConfigService {
// 关联写入数据库
const chatForBot = await this.tgBot.getChat(chat.id);
status && await status.edit({ text: '正在写数据库…' });
const dbPair = await forwardPairs.add(qEntity, chatForBot);
const dbPair = await this.instance.forwardPairs.add(qEntity, chatForBot);
isFinish = true;
// 更新头像
@ -227,7 +226,7 @@ export default class ConfigService {
const tgChat = await this.tgBot.getChat(tgChatId);
message = `QQ群${qGroup.group_id} (<code>${qGroup.group_id}</code>)已与 ` +
`Telegram 群 ${(tgChat.entity as Api.Channel).title} (<code>${tgChatId}</code>)关联`;
await forwardPairs.add(qGroup, tgChat);
await this.instance.forwardPairs.add(qGroup, tgChat);
}
catch (e) {
message = `错误:<code>${e}</code>`;

View File

@ -2,10 +2,10 @@ import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import { getLogger } from 'log4js';
import { Api } from 'telegram';
import { Pair } from '../models/forwardPairs';
import db from '../models/db';
import { Friend, FriendRecallEvent, GroupRecallEvent } from 'oicq';
import Instance from '../models/Instance';
import { Pair } from '../models/Pair';
export default class DeleteMessageService {
private log = getLogger('DeleteMessageService');

View File

@ -1,7 +1,6 @@
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import { Group, GroupMessageEvent, PrivateMessageEvent, Quotable, segment, Sendable } from 'oicq';
import { Pair } from '../models/forwardPairs';
import { fetchFile, getBigFaceUrl, getImageUrlByMd5 } from '../utils/urls';
import { FileLike, MarkupLike } from 'telegram/define';
import { CustomFile } from 'telegram/client/uploads';
@ -22,6 +21,7 @@ import tgsToGif from '../encoding/tgsToGif';
import axios from 'axios';
import { md5Hex } from '../utils/hashing';
import Instance from '../models/Instance';
import { Pair } from '../models/Pair';
// noinspection FallThroughInSwitchStatementJS
export default class ForwardService {