mirror of https://github.com/Nofated095/Q2TG.git
refactor: 使用实例管理 Controller 生命周期,并将配置存储在数据库。实例可并行运行
This commit is contained in:
parent
415cba38f5
commit
315a2cd544
|
@ -11,40 +11,55 @@ datasource db {
|
|||
}
|
||||
|
||||
model Session {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
dcId Int?
|
||||
port Int?
|
||||
serverAddress String?
|
||||
authKey Bytes?
|
||||
entities Entity[]
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
dcId Int?
|
||||
port Int?
|
||||
serverAddress String?
|
||||
authKey Bytes?
|
||||
entities Entity[]
|
||||
}
|
||||
|
||||
model Entity {
|
||||
id Int @id @default(autoincrement())
|
||||
id Int @id @default(autoincrement())
|
||||
// 源代码里面大概支持 string 和 BigInteger,不如先全都存 String
|
||||
entityId String
|
||||
sessionId Int
|
||||
session Session @relation(fields: [sessionId], references: [id])
|
||||
hash String?
|
||||
username String?
|
||||
phone String?
|
||||
name String?
|
||||
entityId String
|
||||
sessionId Int
|
||||
session Session @relation(fields: [sessionId], references: [id])
|
||||
hash String?
|
||||
username String?
|
||||
phone String?
|
||||
name String?
|
||||
|
||||
@@unique([entityId, sessionId])
|
||||
}
|
||||
|
||||
model Instance {
|
||||
id Int @id @default(autoincrement())
|
||||
owner BigInt @default(0)
|
||||
qqUin BigInt @default(0)
|
||||
qqPassword String @default("")
|
||||
qqPlatform Int @default(0)
|
||||
workMode String @default("")
|
||||
isSetup Boolean @default(false)
|
||||
botToken String?
|
||||
Message Message[]
|
||||
ForwardPair ForwardPair[]
|
||||
}
|
||||
|
||||
model Message {
|
||||
id Int @id @default(autoincrement())
|
||||
qqRoomId BigInt @db.BigInt
|
||||
qqSenderId BigInt @db.BigInt
|
||||
qqRoomId BigInt @db.BigInt
|
||||
qqSenderId BigInt @db.BigInt
|
||||
time Int
|
||||
brief String?
|
||||
seq Int
|
||||
rand Int
|
||||
pktnum Int
|
||||
tgChatId BigInt @db.BigInt
|
||||
tgChatId BigInt @db.BigInt
|
||||
tgMsgId Int
|
||||
instanceId Int @default(0)
|
||||
instance Instance @relation(fields: [instanceId], references: [id])
|
||||
|
||||
@@unique([qqRoomId, qqSenderId, seq, rand, pktnum, time])
|
||||
@@unique([tgChatId, tgMsgId])
|
||||
|
@ -52,29 +67,31 @@ model Message {
|
|||
|
||||
model ForwardPair {
|
||||
id Int @id @default(autoincrement())
|
||||
qqRoomId BigInt @unique @db.BigInt
|
||||
tgChatId BigInt @unique @db.BigInt
|
||||
qqRoomId BigInt @unique @db.BigInt
|
||||
tgChatId BigInt @unique @db.BigInt
|
||||
avatarCache AvatarCache[]
|
||||
instanceId Int @default(0)
|
||||
instance Instance @relation(fields: [instanceId], references: [id])
|
||||
}
|
||||
|
||||
model File {
|
||||
id Int @id @default(autoincrement())
|
||||
roomId BigInt @db.BigInt
|
||||
fileId String
|
||||
info String
|
||||
|
||||
@@unique([roomId, fileId])
|
||||
id Int @id @default(autoincrement())
|
||||
roomId BigInt @db.BigInt
|
||||
fileId String
|
||||
info String
|
||||
}
|
||||
|
||||
model FlashPhoto {
|
||||
id Int @id @default(autoincrement())
|
||||
id Int @id @default(autoincrement())
|
||||
photoMd5 String
|
||||
views FlashPhotoView[]
|
||||
}
|
||||
|
||||
model FlashPhotoView {
|
||||
id Int @id @default(autoincrement())
|
||||
id Int @id @default(autoincrement())
|
||||
flashPhotoId Int
|
||||
viewerId BigInt @db.BigInt
|
||||
flashPhoto FlashPhoto @relation(fields: [flashPhotoId], references: [id])
|
||||
viewerId BigInt @db.BigInt
|
||||
|
||||
@@unique([flashPhotoId, viewerId])
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import CallbackQueryHelper from '../helpers/CallbackQueryHelper';
|
|||
import { CallbackQuery } from 'telegram/events/CallbackQuery';
|
||||
import os from 'os';
|
||||
import TelegramChat from './TelegramChat';
|
||||
import TelegramSession from './TelegramSession';
|
||||
import TelegramSession from '../models/TelegramSession';
|
||||
import { LogLevel } from 'telegram/extensions/Logger';
|
||||
|
||||
type MessageHandler = (message: Api.Message) => Promise<boolean | void>;
|
||||
|
|
|
@ -2,29 +2,30 @@ import { Api } from 'telegram';
|
|||
import Telegram from '../client/Telegram';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import ConfigService from '../services/ConfigService';
|
||||
import { config } from '../providers/userConfig';
|
||||
import regExps from '../constants/regExps';
|
||||
import forwardPairs from '../providers/forwardPairs';
|
||||
import forwardPairs from '../models/forwardPairs';
|
||||
import { GroupMessageEvent, MemberIncreaseEvent, PrivateMessageEvent } from 'oicq';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
export default class ConfigController {
|
||||
private readonly configService: ConfigService;
|
||||
private readonly createPrivateMessageGroupBlockList = new Map<number, Promise<void>>();
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly tgUser: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
this.configService = new ConfigService(tgBot, tgUser, oicq);
|
||||
this.configService = new ConfigService(this.instance, tgBot, tgUser, oicq);
|
||||
tgBot.addNewMessageEventHandler(this.handleMessage);
|
||||
tgBot.addNewServiceMessageEventHandler(this.handleServiceMessage);
|
||||
oicq.addNewMessageEventHandler(this.handleQqMessage);
|
||||
config.workMode === 'personal' && oicq.on('notice.group.increase', this.handleMemberIncrease);
|
||||
this.instance.workMode === 'personal' && oicq.on('notice.group.increase', this.handleMemberIncrease);
|
||||
this.configService.configCommands();
|
||||
config.workMode === 'personal' && this.configService.setupFilter();
|
||||
this.instance.workMode === 'personal' && this.configService.setupFilter();
|
||||
}
|
||||
|
||||
private handleMessage = async (message: Api.Message) => {
|
||||
if (!message.sender.id.eq(config.owner)) {
|
||||
if (!message.sender.id.eq(this.instance.owner)) {
|
||||
return false;
|
||||
}
|
||||
const messageSplit = message.message.split(' ');
|
||||
|
@ -37,7 +38,7 @@ export default class ConfigController {
|
|||
return false;
|
||||
}
|
||||
else if (message.isPrivate) {
|
||||
if (config.workMode === 'personal') {
|
||||
if (this.instance.workMode === 'personal') {
|
||||
switch (messageSplit[0]) {
|
||||
case '/addfriend':
|
||||
await this.configService.addFriend();
|
||||
|
@ -77,7 +78,7 @@ export default class ConfigController {
|
|||
// 会自动写入数据库
|
||||
pair.tg = await this.tgBot.getChat(message.action.channelId);
|
||||
// 升级之后 bot 的管理权限可能没了,需要修复一下
|
||||
if (config.workMode === 'personal') {
|
||||
if (this.instance.workMode === 'personal') {
|
||||
const chatForUser = await this.tgUser.getChat(message.action.channelId);
|
||||
await chatForUser.setAdmin(this.tgBot.me.username);
|
||||
}
|
||||
|
|
|
@ -3,18 +3,20 @@ import { getLogger } from 'log4js';
|
|||
import Telegram from '../client/Telegram';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import { Api } from 'telegram';
|
||||
import forwardPairs from '../providers/forwardPairs';
|
||||
import forwardPairs from '../models/forwardPairs';
|
||||
import { FriendRecallEvent, GroupRecallEvent } from 'oicq';
|
||||
import { DeletedMessageEvent } from 'telegram/events/DeletedMessage';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
export default class DeleteMessageController {
|
||||
private readonly deleteMessageService: DeleteMessageService;
|
||||
private readonly log = getLogger('DeleteMessageController');
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly tgUser: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
this.deleteMessageService = new DeleteMessageService(tgBot, oicq);
|
||||
this.deleteMessageService = new DeleteMessageService(this.instance, tgBot, oicq);
|
||||
tgBot.addNewMessageEventHandler(this.onTelegramMessage);
|
||||
tgBot.addEditedMessageEventHandler(this.onTelegramEditMessage);
|
||||
tgUser.addDeletedMessageEventHandler(this.onTgDeletedMessage);
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
import Telegram from '../client/Telegram';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import { Api } from 'telegram';
|
||||
import db from '../providers/db';
|
||||
import db from '../models/db';
|
||||
import { Button } from 'telegram/tl/custom/button';
|
||||
import { getLogger } from 'log4js';
|
||||
import { CustomFile } from 'telegram/client/uploads';
|
||||
import { fetchFile, getImageUrlByMd5 } from '../utils/urls';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
const REGEX = /^\/start (file|flash)-(\d+)$/;
|
||||
|
||||
export default class FileAndFlashPhotoController {
|
||||
private readonly log = getLogger('FileController');
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
tgBot.addNewMessageEventHandler(this.onTelegramMessage);
|
||||
}
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
import Telegram from '../client/Telegram';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import ForwardService from '../services/ForwardService';
|
||||
import forwardPairs from '../providers/forwardPairs';
|
||||
import forwardPairs from '../models/forwardPairs';
|
||||
import { GroupMessageEvent, PrivateMessageEvent } from 'oicq';
|
||||
import db from '../providers/db';
|
||||
import db from '../models/db';
|
||||
import { Api } from 'telegram';
|
||||
import { getLogger } from 'log4js';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
export default class ForwardController {
|
||||
private readonly forwardService: ForwardService;
|
||||
private readonly log = getLogger('ForwardController');
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly tgUser: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
this.forwardService = new ForwardService(tgBot, oicq);
|
||||
this.forwardService = new ForwardService(this.instance, tgBot, oicq);
|
||||
forwardPairs.init(oicq, tgBot)
|
||||
.then(() => oicq.addNewMessageEventHandler(this.onQqMessage))
|
||||
.then(() => tgBot.addNewMessageEventHandler(this.onTelegramMessage))
|
||||
|
|
|
@ -9,6 +9,7 @@ import commands from '../constants/commands';
|
|||
import { WorkMode } from '../types/definitions';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import { md5Hex } from '../utils/hashing';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
export default class SetupController {
|
||||
private readonly setupService: SetupService;
|
||||
|
@ -19,8 +20,9 @@ export default class SetupController {
|
|||
private tgUser: Telegram;
|
||||
private oicq: OicqClient;
|
||||
|
||||
constructor(private readonly tgBot: Telegram) {
|
||||
this.setupService = new SetupService(tgBot);
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram) {
|
||||
this.setupService = new SetupService(this.instance, tgBot);
|
||||
tgBot.addNewMessageEventHandler(this.handleMessage);
|
||||
tgBot.setCommands(commands.preSetupCommands, new Api.BotCommandScopeUsers());
|
||||
}
|
||||
|
|
42
src/index.ts
42
src/index.ts
|
@ -1,12 +1,5 @@
|
|||
import Telegram from './client/Telegram';
|
||||
import { config } from './providers/userConfig';
|
||||
import { configure, getLogger } from 'log4js';
|
||||
import SetupController from './controllers/SetupController';
|
||||
import OicqClient from './client/OicqClient';
|
||||
import ConfigController from './controllers/ConfigController';
|
||||
import ForwardController from './controllers/ForwardController';
|
||||
import FileAndFlashPhotoController from './controllers/FileAndFlashPhotoController';
|
||||
import DeleteMessageController from './controllers/DeleteMessageController';
|
||||
import Instance from './models/Instance';
|
||||
|
||||
(async () => {
|
||||
configure({
|
||||
|
@ -21,36 +14,5 @@ import DeleteMessageController from './controllers/DeleteMessageController';
|
|||
process.on('unhandledRejection', error => {
|
||||
log.error('UnhandledException: ', error);
|
||||
});
|
||||
|
||||
log.debug('正在登录 TG Bot');
|
||||
const tgBot = await Telegram.create({
|
||||
botAuthToken: process.env.TG_BOT_TOKEN,
|
||||
}, 'bot');
|
||||
|
||||
let tgUser: Telegram, oicq: OicqClient;
|
||||
log.debug('TG Bot 登录完成');
|
||||
if (!config.isSetup) {
|
||||
log.info('当前服务器未配置,请向 Bot 发送 /setup 来设置');
|
||||
const setupController = new SetupController(tgBot);
|
||||
({ tgUser, oicq } = await setupController.waitForFinish());
|
||||
}
|
||||
else {
|
||||
log.debug('正在登录 TG UserBot');
|
||||
tgUser = await Telegram.connect('user');
|
||||
log.debug('TG UserBot 登录完成');
|
||||
log.debug('正在登录 OICQ');
|
||||
oicq = await OicqClient.create({
|
||||
uin: config.qqUin,
|
||||
password: config.qqPassword,
|
||||
platform: config.qqPlatform,
|
||||
onVerifyDevice: () => null,
|
||||
onVerifySlider: () => null,
|
||||
onQrCode: () => null,
|
||||
});
|
||||
log.debug('OICQ 登录完成');
|
||||
}
|
||||
new ConfigController(tgBot, tgUser, oicq);
|
||||
new DeleteMessageController(tgBot, tgUser, oicq);
|
||||
new ForwardController(tgBot, tgUser, oicq);
|
||||
new FileAndFlashPhotoController(tgBot, oicq);
|
||||
await Instance.start(0);
|
||||
})();
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
import { WorkMode } from '../types/definitions';
|
||||
import db from './db';
|
||||
import { Platform } from 'oicq';
|
||||
import ConfigController from '../controllers/ConfigController';
|
||||
import SetupController from '../controllers/SetupController';
|
||||
import ForwardController from '../controllers/ForwardController';
|
||||
import DeleteMessageController from '../controllers/DeleteMessageController';
|
||||
import FileAndFlashPhotoController from '../controllers/FileAndFlashPhotoController';
|
||||
import Telegram from '../client/Telegram';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import { getLogger, Logger } from 'log4js';
|
||||
|
||||
export default class Instance {
|
||||
private _owner = 0;
|
||||
private _qqUin = 0;
|
||||
private _qqPassword = '';
|
||||
private _qqPlatform = 0;
|
||||
private _isSetup = false;
|
||||
private _workMode = '';
|
||||
|
||||
private readonly log: Logger;
|
||||
|
||||
private setupController: SetupController;
|
||||
private configController: ConfigController;
|
||||
private deleteMessageController: DeleteMessageController;
|
||||
private forwardController: ForwardController;
|
||||
private fileAndFlashPhotoController: FileAndFlashPhotoController;
|
||||
|
||||
private constructor(public readonly id: number) {
|
||||
this.log = getLogger(`Instance ${this.id}`);
|
||||
}
|
||||
|
||||
private async load() {
|
||||
const dbEntry = await db.instance.findFirst({
|
||||
where: { id: this.id },
|
||||
});
|
||||
|
||||
if (!dbEntry) {
|
||||
if (this.id === 0) {
|
||||
// 创建零号实例
|
||||
await db.instance.create({
|
||||
data: { id: 0 },
|
||||
});
|
||||
return;
|
||||
}
|
||||
else
|
||||
throw new Error('Instance not found');
|
||||
}
|
||||
|
||||
this._owner = Number(dbEntry.owner);
|
||||
this._qqUin = Number(dbEntry.qqUin);
|
||||
this._qqPassword = dbEntry.qqPassword;
|
||||
this._qqPlatform = dbEntry.qqPlatform;
|
||||
this._isSetup = dbEntry.isSetup;
|
||||
this._workMode = dbEntry.workMode;
|
||||
}
|
||||
|
||||
private async init() {
|
||||
this.log.debug('正在登录 TG Bot');
|
||||
const tgBot = await Telegram.create({
|
||||
botAuthToken: process.env.TG_BOT_TOKEN,
|
||||
}, 'bot');
|
||||
|
||||
let tgUser: Telegram, oicq: OicqClient;
|
||||
this.log.debug('TG Bot 登录完成');
|
||||
if (!this.isSetup) {
|
||||
this.log.info('当前服务器未配置,请向 Bot 发送 /setup 来设置');
|
||||
this.setupController = new SetupController(this, tgBot);
|
||||
({ tgUser, oicq } = await this.setupController.waitForFinish());
|
||||
}
|
||||
else {
|
||||
this.log.debug('正在登录 TG UserBot');
|
||||
tgUser = await Telegram.connect('user');
|
||||
this.log.debug('TG UserBot 登录完成');
|
||||
this.log.debug('正在登录 OICQ');
|
||||
oicq = await OicqClient.create({
|
||||
uin: this.qqUin,
|
||||
password: this.qqPassword,
|
||||
platform: this.qqPlatform,
|
||||
onVerifyDevice: () => null,
|
||||
onVerifySlider: () => null,
|
||||
onQrCode: () => null,
|
||||
});
|
||||
this.log.debug('OICQ 登录完成');
|
||||
}
|
||||
this.configController = new ConfigController(this, tgBot, tgUser, oicq);
|
||||
this.deleteMessageController = new DeleteMessageController(this, tgBot, tgUser, oicq);
|
||||
this.forwardController = new ForwardController(this, tgBot, tgUser, oicq);
|
||||
this.fileAndFlashPhotoController = new FileAndFlashPhotoController(this, tgBot, oicq);
|
||||
}
|
||||
|
||||
public static async start(instanceId: number) {
|
||||
const instance = new this(instanceId);
|
||||
await instance.load();
|
||||
await instance.init();
|
||||
return instance;
|
||||
}
|
||||
|
||||
get owner() {
|
||||
return this._owner;
|
||||
}
|
||||
|
||||
get qqUin() {
|
||||
return this._qqUin;
|
||||
}
|
||||
|
||||
get qqPassword() {
|
||||
return this._qqPassword;
|
||||
}
|
||||
|
||||
get qqPlatform() {
|
||||
return this._qqPlatform as Platform;
|
||||
}
|
||||
|
||||
get isSetup() {
|
||||
return this._isSetup;
|
||||
}
|
||||
|
||||
get workMode() {
|
||||
return this._workMode as WorkMode;
|
||||
}
|
||||
|
||||
set owner(owner: number) {
|
||||
this._owner = owner;
|
||||
db.instance.update({
|
||||
data: { owner },
|
||||
where: { id: this.id },
|
||||
})
|
||||
.then(() => this.log.trace(owner));
|
||||
}
|
||||
|
||||
set qqUin(qqUin: number) {
|
||||
this._qqUin = qqUin;
|
||||
db.instance.update({
|
||||
data: { qqUin },
|
||||
where: { id: this.id },
|
||||
})
|
||||
.then(() => this.log.trace(qqUin));
|
||||
}
|
||||
|
||||
set qqPassword(qqPassword: string) {
|
||||
this._qqPassword = qqPassword;
|
||||
db.instance.update({
|
||||
data: { qqPassword },
|
||||
where: { id: this.id },
|
||||
})
|
||||
.then(() => this.log.trace(qqPassword));
|
||||
}
|
||||
|
||||
set qqPlatform(qqPlatform: Platform) {
|
||||
this._qqPlatform = qqPlatform;
|
||||
db.instance.update({
|
||||
data: { qqPlatform },
|
||||
where: { id: this.id },
|
||||
})
|
||||
.then(() => this.log.trace(qqPlatform));
|
||||
}
|
||||
|
||||
set isSetup(isSetup: boolean) {
|
||||
this._isSetup = isSetup;
|
||||
db.instance.update({
|
||||
data: { isSetup },
|
||||
where: { id: this.id },
|
||||
})
|
||||
.then(() => this.log.trace(isSetup));
|
||||
}
|
||||
|
||||
set workMode(workMode: WorkMode) {
|
||||
this._workMode = workMode;
|
||||
db.instance.update({
|
||||
data: { workMode },
|
||||
where: { id: this.id },
|
||||
})
|
||||
.then(() => this.log.trace(workMode));
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { MemorySession } from 'telegram/sessions';
|
||||
import db from '../providers/db';
|
||||
import db from './db';
|
||||
import { AuthKey } from 'telegram/crypto/AuthKey';
|
||||
import { getLogger } from 'log4js';
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
import fs from 'fs';
|
||||
import fsP from 'fs/promises';
|
||||
import { WorkMode } from '../types/definitions';
|
||||
|
||||
type UserConfig = {
|
||||
owner: number
|
||||
qqUin: number;
|
||||
qqPassword: string;
|
||||
qqPlatform: number
|
||||
isSetup: boolean;
|
||||
workMode?: WorkMode
|
||||
}
|
||||
|
||||
const CONFIG_PATH = './data/config.json';
|
||||
|
||||
const defaultConfig: UserConfig = {
|
||||
owner: 0,
|
||||
qqUin: 0,
|
||||
qqPassword: '',
|
||||
qqPlatform: 0,
|
||||
isSetup: false,
|
||||
workMode: undefined,
|
||||
};
|
||||
|
||||
export const config: UserConfig = fs.existsSync(CONFIG_PATH) ?
|
||||
JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8')) :
|
||||
defaultConfig;
|
||||
|
||||
export const saveConfig = async () => {
|
||||
await fsP.writeFile(CONFIG_PATH, JSON.stringify(config, null, 0), 'utf8');
|
||||
};
|
|
@ -1,18 +1,17 @@
|
|||
import Telegram from '../client/Telegram';
|
||||
import { Friend, FriendInfo, Group } from 'oicq';
|
||||
import { config } from '../providers/userConfig';
|
||||
import { Button } from 'telegram/tl/custom/button';
|
||||
import { getLogger } from 'log4js';
|
||||
import { getAvatar } from '../utils/urls';
|
||||
import { CustomFile } from 'telegram/client/uploads';
|
||||
import db from '../providers/db';
|
||||
import db from '../models/db';
|
||||
import { Api, utils } from 'telegram';
|
||||
import commands from '../constants/commands';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import { md5 } from '../utils/hashing';
|
||||
import TelegramChat from '../client/TelegramChat';
|
||||
import forwardPairs from '../providers/forwardPairs';
|
||||
import bigInt from 'big-integer';
|
||||
import forwardPairs from '../models/forwardPairs';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
const DEFAULT_FILTER_ID = 114; // 514
|
||||
|
||||
|
@ -20,10 +19,11 @@ export default class ConfigService {
|
|||
private owner: Promise<TelegramChat>;
|
||||
private log = getLogger('ConfigService');
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly tgUser: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
this.owner = tgBot.getChat(config.owner);
|
||||
this.owner = tgBot.getChat(this.instance.owner);
|
||||
}
|
||||
|
||||
private getAssociateLink(roomId: number) {
|
||||
|
@ -33,7 +33,7 @@ export default class ConfigService {
|
|||
public async configCommands() {
|
||||
await this.tgBot.setCommands([], new Api.BotCommandScopeUsers());
|
||||
await this.tgBot.setCommands(
|
||||
config.workMode === 'personal' ? commands.personalPrivateCommands : commands.groupPrivateCommands,
|
||||
this.instance.workMode === 'personal' ? commands.personalPrivateCommands : commands.groupPrivateCommands,
|
||||
new Api.BotCommandScopePeer({
|
||||
peer: (await this.owner).inputPeer,
|
||||
}),
|
||||
|
@ -47,7 +47,7 @@ export default class ConfigService {
|
|||
const qGroups = Array.from(this.oicq.gl).map(e => e[1])
|
||||
.filter(it => !forwardPairs.find(-it.group_id));
|
||||
const buttons = qGroups.map(e =>
|
||||
config.workMode === 'personal' ?
|
||||
this.instance.workMode === 'personal' ?
|
||||
[Button.inline(
|
||||
`${e.group_name} (${e.group_id})`,
|
||||
this.tgBot.registerCallback(() => this.createGroupAndLink(-e.group_id, e.group_name)),
|
||||
|
@ -57,7 +57,7 @@ export default class ConfigService {
|
|||
this.getAssociateLink(-e.group_id),
|
||||
)]);
|
||||
await (await this.owner).createPaginatedInlineSelector(
|
||||
'选择 QQ 群组' + (config.workMode === 'group' ? '\n然后选择在 TG 中的群组' : ''), buttons);
|
||||
'选择 QQ 群组' + (this.instance.workMode === 'group' ? '\n然后选择在 TG 中的群组' : ''), buttons);
|
||||
}
|
||||
|
||||
// 只可能是 personal 运行模式
|
||||
|
|
|
@ -2,15 +2,16 @@ import Telegram from '../client/Telegram';
|
|||
import OicqClient from '../client/OicqClient';
|
||||
import { getLogger } from 'log4js';
|
||||
import { Api } from 'telegram';
|
||||
import { Pair } from '../providers/forwardPairs';
|
||||
import { config } from '../providers/userConfig';
|
||||
import db from '../providers/db';
|
||||
import { Pair } from '../models/forwardPairs';
|
||||
import db from '../models/db';
|
||||
import { Friend, FriendRecallEvent, GroupRecallEvent } from 'oicq';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
export default class DeleteMessageService {
|
||||
private log = getLogger('DeleteMessageService');
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
}
|
||||
|
||||
|
@ -36,12 +37,12 @@ export default class DeleteMessageService {
|
|||
console.log(123);
|
||||
const tipMsg = await pair.tg.sendMessage({
|
||||
message: '撤回 QQ 中对应的消息失败' +
|
||||
(config.workMode === 'group' ? ',QQ Bot 需要是管理员' : '') +
|
||||
(this.instance.workMode === 'group' ? ',QQ Bot 需要是管理员' : '') +
|
||||
(isOthersMsg ? ',而且无法撤回其他管理员的消息' : '') +
|
||||
(e.message ? '\n' + e.message : ''),
|
||||
silent: true,
|
||||
});
|
||||
config.workMode === 'group' && setTimeout(async () => await tipMsg.delete({ revoke: true }), 5000);
|
||||
this.instance.workMode === 'group' && setTimeout(async () => await tipMsg.delete({ revoke: true }), 5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ export default class DeleteMessageService {
|
|||
const replyMessage = await message.getReplyMessage();
|
||||
if (replyMessage instanceof Api.Message) {
|
||||
// 检查权限并撤回被回复的消息
|
||||
let hasPermission = config.workMode === 'personal' || replyMessage.senderId?.eq(message.senderId);
|
||||
let hasPermission = this.instance.workMode === 'personal' || replyMessage.senderId?.eq(message.senderId);
|
||||
if (!hasPermission && message.chat instanceof Api.Channel) {
|
||||
// 可能是超级群
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Telegram from '../client/Telegram';
|
||||
import OicqClient from '../client/OicqClient';
|
||||
import { Group, GroupMessageEvent, PrivateMessageEvent, Quotable, segment, Sendable } from 'oicq';
|
||||
import { Pair } from '../providers/forwardPairs';
|
||||
import { Pair } from '../models/forwardPairs';
|
||||
import { fetchFile, getBigFaceUrl, getImageUrlByMd5 } from '../utils/urls';
|
||||
import { FileLike, MarkupLike } from 'telegram/define';
|
||||
import { CustomFile } from 'telegram/client/uploads';
|
||||
|
@ -9,11 +9,10 @@ import { getLogger } from 'log4js';
|
|||
import path from 'path';
|
||||
import exts from '../constants/exts';
|
||||
import helper from '../helpers/forwardHelper';
|
||||
import db from '../providers/db';
|
||||
import db from '../models/db';
|
||||
import { Button } from 'telegram/tl/custom/button';
|
||||
import { SendMessageParams } from 'telegram/client/messages';
|
||||
import { Api } from 'telegram';
|
||||
import { config } from '../providers/userConfig';
|
||||
import { file as createTempFile, FileResult } from 'tmp-promise';
|
||||
import fsP from 'fs/promises';
|
||||
import eviltransform from 'eviltransform';
|
||||
|
@ -22,12 +21,14 @@ import fs from 'fs';
|
|||
import tgsToGif from '../encoding/tgsToGif';
|
||||
import axios from 'axios';
|
||||
import { md5Hex } from '../utils/hashing';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
// noinspection FallThroughInSwitchStatementJS
|
||||
export default class ForwardService {
|
||||
private log = getLogger('ForwardService');
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram,
|
||||
private readonly oicq: OicqClient) {
|
||||
}
|
||||
|
||||
|
@ -81,7 +82,7 @@ export default class ForwardService {
|
|||
}
|
||||
break;
|
||||
case 'flash': {
|
||||
message += `[闪照]\n${config.workMode === 'group' ? '每人' : ''}只能查看一次`;
|
||||
message += `[闪照]\n${this.instance.workMode === 'group' ? '每人' : ''}只能查看一次`;
|
||||
const dbEntry = await db.flashPhoto.create({
|
||||
data: { photoMd5: (elem.file as string).substring(0, 32) },
|
||||
});
|
||||
|
@ -228,7 +229,7 @@ export default class ForwardService {
|
|||
const chain: Sendable = [];
|
||||
// 这条消息在 tg 中被回复的时候显示的
|
||||
let brief = '';
|
||||
config.workMode === 'group' && chain.push(helper.getUserDisplayName(message.sender) +
|
||||
this.instance.workMode === 'group' && chain.push(helper.getUserDisplayName(message.sender) +
|
||||
(message.forward ? ' Forwarded from ' + helper.getUserDisplayName(message.forward.chat || message.forward.sender) : '') +
|
||||
': \n');
|
||||
if (message.photo instanceof Api.Photo ||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import Telegram from '../client/Telegram';
|
||||
import { config, saveConfig } from '../providers/userConfig';
|
||||
import { getLogger } from 'log4js';
|
||||
import { BigInteger } from 'big-integer';
|
||||
import { Platform } from 'oicq';
|
||||
|
@ -9,16 +8,18 @@ import { Button } from 'telegram/tl/custom/button';
|
|||
import { CustomFile } from 'telegram/client/uploads';
|
||||
import { WorkMode } from '../types/definitions';
|
||||
import TelegramChat from '../client/TelegramChat';
|
||||
import Instance from '../models/Instance';
|
||||
|
||||
export default class SetupService {
|
||||
private owner: TelegramChat;
|
||||
private log = getLogger('SetupService');
|
||||
|
||||
constructor(private readonly tgBot: Telegram) {
|
||||
constructor(private readonly instance: Instance,
|
||||
private readonly tgBot: Telegram) {
|
||||
}
|
||||
|
||||
public setWorkMode(mode: WorkMode) {
|
||||
config.workMode = mode;
|
||||
this.instance.workMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,7 +30,7 @@ export default class SetupService {
|
|||
public async claimOwner(userId: number | BigInteger) {
|
||||
userId = Number(userId);
|
||||
if (!this.owner) {
|
||||
config.owner = userId;
|
||||
this.instance.owner = userId;
|
||||
await this.setupOwner();
|
||||
this.log.info(`用户 ID: ${userId} 成为了 Bot 主人`);
|
||||
return true;
|
||||
|
@ -38,8 +39,8 @@ export default class SetupService {
|
|||
}
|
||||
|
||||
private async setupOwner() {
|
||||
if (!this.owner && config.owner) {
|
||||
this.owner = await this.tgBot.getChat(config.owner);
|
||||
if (!this.owner && this.instance.owner) {
|
||||
this.owner = await this.tgBot.getChat(this.instance.owner);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,13 +108,12 @@ export default class SetupService {
|
|||
}
|
||||
|
||||
public saveOicqLoginInfo(uin: number, password: string, platform: Platform) {
|
||||
config.qqUin = uin;
|
||||
config.qqPassword = password;
|
||||
config.qqPlatform = platform;
|
||||
this.instance.qqUin = uin;
|
||||
this.instance.qqPassword = password;
|
||||
this.instance.qqPlatform = platform;
|
||||
}
|
||||
|
||||
public async finishConfig() {
|
||||
config.isSetup = true;
|
||||
await saveConfig();
|
||||
this.instance.isSetup = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue