Q2TG/src/controllers/SetupController.ts

177 lines
6.7 KiB
TypeScript
Raw Normal View History

2022-02-23 09:11:04 +00:00
import Telegram from '../client/Telegram';
2022-02-17 13:09:12 +00:00
import SetupService from '../services/SetupService';
import { Api } from 'telegram';
2022-03-07 10:14:45 +00:00
import { getLogger, Logger } from 'log4js';
2022-02-18 06:22:29 +00:00
import { Button } from 'telegram/tl/custom/button';
import setupHelper from '../helpers/setupHelper';
import commands from '../constants/commands';
import { WorkMode } from '../types/definitions';
2022-02-23 06:09:54 +00:00
import OicqClient from '../client/OicqClient';
2022-03-07 07:15:29 +00:00
import { md5Hex } from '../utils/hashing';
import Instance from '../models/Instance';
2022-02-17 13:09:12 +00:00
export default class SetupController {
private readonly setupService: SetupService;
2022-03-07 10:14:45 +00:00
private readonly log: Logger;
2022-02-17 13:09:12 +00:00
private isInProgress = false;
private waitForFinishCallbacks: Array<(ret: { tgUser: Telegram, oicq: OicqClient }) => unknown> = [];
2022-02-17 13:09:12 +00:00
// 创建的 UserBot
private tgUser: Telegram;
2022-02-18 06:22:29 +00:00
private oicq: OicqClient;
2022-02-17 13:09:12 +00:00
constructor(private readonly instance: Instance,
private readonly tgBot: Telegram) {
2022-03-07 10:14:45 +00:00
this.log = getLogger(`SetupController - ${instance.id}`);
this.setupService = new SetupService(this.instance, tgBot);
2022-02-17 13:09:12 +00:00
tgBot.addNewMessageEventHandler(this.handleMessage);
tgBot.setCommands(commands.preSetupCommands, new Api.BotCommandScopeUsers());
2022-02-17 13:09:12 +00:00
}
private handleMessage = async (message: Api.Message) => {
2022-02-20 08:25:30 +00:00
if (this.isInProgress || !message.isPrivate) {
return false;
2022-02-17 13:09:12 +00:00
}
if (message.text === '/setup' || message.text === '/start setup') {
2022-02-17 13:09:12 +00:00
this.isInProgress = true;
2022-02-17 15:26:48 +00:00
await this.doSetup(Number(message.sender.id));
await this.finishSetup();
2022-02-17 13:09:12 +00:00
return true;
}
return false;
};
2022-02-17 15:26:48 +00:00
private async doSetup(ownerId: number) {
2022-02-18 06:22:29 +00:00
// 设置 owner
2022-02-17 15:26:48 +00:00
try {
2022-02-18 06:22:29 +00:00
await this.setupService.claimOwner(ownerId);
2022-02-17 15:26:48 +00:00
}
catch (e) {
this.log.error('Claim Owner 失败', e);
this.isInProgress = false;
throw e;
}
2022-02-19 04:06:43 +00:00
// 设置工作模式
let workMode: WorkMode | '' = '';
2022-02-19 04:06:43 +00:00
try {
while (!workMode) {
const workModeText = await this.setupService.waitForOwnerInput('欢迎使用 Q2TG v2\n' +
2022-03-30 07:21:13 +00:00
'请选择工作模式,关于工作模式的区别请查看<a href="https://github.com/Clansty/Q2TG#%E5%85%B3%E4%BA%8E%E6%A8%A1%E5%BC%8F">这里</a>', [
2022-02-19 04:06:43 +00:00
[Button.text('个人模式', true, true)],
[Button.text('群组模式', true, true)],
]);
workMode = setupHelper.convertTextToWorkMode(workModeText);
}
this.setupService.setWorkMode(workMode);
}
catch (e) {
this.log.error('设置工作模式失败', e);
this.isInProgress = false;
throw e;
}
2022-02-18 06:22:29 +00:00
// 登录 oicq
if (this.instance.qq) {
await this.setupService.informOwner('正在登录已设置好的 QQ');
this.oicq = await OicqClient.create({
id: this.instance.qq.id,
uin: Number(this.instance.qq.uin),
password: this.instance.qq.password,
platform: this.instance.qq.platform,
signApi: this.instance.qq.signApi,
signVer: this.instance.qq.signVer,
signDockerId: this.instance.qq.signDockerId,
onVerifyDevice: async (phone) => {
return await this.setupService.waitForOwnerInput(`请输入手机 ${phone} 收到的验证码`);
},
onVerifySlider: async (url) => {
return await this.setupService.waitForOwnerInput(`收到滑块验证码 <code>${url}</code>\n` +
'请使用<a href="https://github.com/mzdluo123/TxCaptchaHelper/releases">此软件</a>验证并输入 Ticket',
);
},
});
}
else
try {
let uin = NaN;
while (isNaN(uin)) {
uin = Number(await this.setupService.waitForOwnerInput('请输入要登录 QQ 号'));
}
const platformText = await this.setupService.waitForOwnerInput('请选择登录协议', [
[Button.text('安卓手机', true, true)],
[Button.text('安卓平板', true, true)],
[Button.text('iPad', true, true)],
]);
const platform = setupHelper.convertTextToPlatform(platformText);
let signApi: string;
if (!process.env.SIGN_API) {
signApi = await this.setupService.waitForOwnerInput('请输入签名服务器地址', [
[Button.text('不需要签名服务器', true, true)],
]);
signApi = setupHelper.checkSignApiAddress(signApi);
}
let signVer: string;
2023-07-29 17:48:06 +00:00
if (signApi && !process.env.SIGN_VER) {
signVer = await this.setupService.waitForOwnerInput('请输入签名服务器版本,当前支持安卓(8.9.63、8.9.68、8.9.70)、Tim(3.5.1、3.5.2)', [
[Button.text('8.9.63', true, true)],
[Button.text('8.9.68', true, true)],
[Button.text('8.9.70', true, true)],
[Button.text('3.5.1', true, true)],
[Button.text('3.5.2', true, true)],
]);
}
let password = await this.setupService.waitForOwnerInput('请输入密码', undefined, true);
password = md5Hex(password);
this.oicq = await this.setupService.createOicq(uin, password, platform, signApi, signVer);
this.instance.qqBotId = this.oicq.id;
await this.setupService.informOwner(`登录成功`);
}
catch (e) {
this.log.error('登录 OICQ 失败', e);
await this.setupService.informOwner(`登录失败\n${e.message}`);
this.isInProgress = false;
throw e;
}
2022-02-18 06:22:29 +00:00
// 登录 tg UserBot
if (this.instance.userSessionId) {
await this.setupService.informOwner('userSessionId 已经存在,跳过');
this.tgUser = await Telegram.connect(this.instance.userSessionId);
2022-02-17 15:26:48 +00:00
}
else
try {
const phoneNumber = await this.setupService.waitForOwnerInput('创建 Telegram UserBot请输入你的手机号码需要带国家区号例如+86');
await this.setupService.informOwner('正在登录,请稍候…');
this.tgUser = await this.setupService.createUserBot(phoneNumber);
this.instance.userSessionId = this.tgUser.sessionId;
await this.setupService.informOwner(`登录成功\n请使用下面的菜单开始创建转发`);
}
catch (e) {
this.log.error('创建 UserBot 失败', e);
2023-11-08 07:50:06 +00:00
await this.setupService.informOwner(`登录失败\n${e.message}`);
this.isInProgress = false;
throw e;
}
2022-02-17 15:26:48 +00:00
}
private async finishSetup() {
this.tgBot.removeNewMessageEventHandler(this.handleMessage);
this.isInProgress = false;
await this.setupService.finishConfig();
this.waitForFinishCallbacks.forEach(e => e({
tgUser: this.tgUser,
oicq: this.oicq,
2022-02-17 15:26:48 +00:00
}));
}
public waitForFinish() {
return new Promise<{ tgUser: Telegram, oicq: OicqClient }>(resolve => {
2022-02-17 15:26:48 +00:00
this.waitForFinishCallbacks.push(resolve);
});
}
2022-02-17 13:09:12 +00:00
}