mirror of https://github.com/Nofated095/Q2TG.git
feat: 新的好友发送消息时自动创建新的 tg 群组
This commit is contained in:
parent
334aa46375
commit
ffdfc90b96
|
@ -1,5 +1,5 @@
|
|||
import { Client, LogLevel, Platform } from 'oicq';
|
||||
import * as Buffer from 'buffer';
|
||||
import { Client, DiscussMessageEvent, GroupMessageEvent, LogLevel, Platform, PrivateMessageEvent } from 'oicq';
|
||||
import Buffer from 'buffer';
|
||||
import { execSync } from 'child_process';
|
||||
import random from '../utils/random';
|
||||
import fs from 'fs';
|
||||
|
@ -9,6 +9,8 @@ import { Config } from 'oicq/lib/client';
|
|||
|
||||
const LOG_LEVEL: LogLevel = 'warn';
|
||||
|
||||
type MessageHandler = (event: PrivateMessageEvent | GroupMessageEvent) => Promise<boolean | void>
|
||||
|
||||
interface CreateOicqParams {
|
||||
uin: number;
|
||||
password: string;
|
||||
|
@ -23,6 +25,8 @@ interface CreateOicqParams {
|
|||
|
||||
// OicqExtended??
|
||||
export default class OicqClient extends Client {
|
||||
private readonly onMessageHandlers: Array<MessageHandler> = [];
|
||||
|
||||
private constructor(uin: number, conf?: Config) {
|
||||
super(uin, conf);
|
||||
}
|
||||
|
@ -59,7 +63,8 @@ export default class OicqClient extends Client {
|
|||
.off('system.login.slider', loginSliderHandler)
|
||||
.off('system.login.qrcode', loginQrCodeHandler)
|
||||
.off('system.login.error', loginErrorHandler)
|
||||
.off('system.online', successLoginHandler);
|
||||
.off('system.online', successLoginHandler)
|
||||
.on('message', client.onMessage);
|
||||
resolve(client);
|
||||
}
|
||||
|
||||
|
@ -73,8 +78,8 @@ export default class OicqClient extends Client {
|
|||
board: 'raincandy',
|
||||
brand: random.pick('GOOGLE', 'XIAOMI', 'HUAWEI', 'SAMSUNG', 'SONY'),
|
||||
model: 'raincandy',
|
||||
wifi_ssid: random.pick('OpenWrt', `Redmi-${random.hex(4)}`,
|
||||
`MiWifi-${random.hex(4)}`, `TP-LINK-${random.hex(6)}`),
|
||||
wifi_ssid: random.pick('OpenWrt', `Redmi-${random.hex(4).toUpperCase()}`,
|
||||
`MiWifi-${random.hex(4).toUpperCase()}`, `TP-LINK-${random.hex(6).toUpperCase()}`),
|
||||
bootloader: random.pick('U-Boot', 'GRUB', 'gummiboot'),
|
||||
android_id: random.hex(16),
|
||||
proc_version: `${execSync('uname -s').toString().replace('\n', '')} version ${execSync('uname -r').toString().replace('\n', '')}`,
|
||||
|
@ -90,7 +95,7 @@ export default class OicqClient extends Client {
|
|||
const client = new this(params.uin, {
|
||||
platform: params.platform,
|
||||
data_dir: path.resolve('./data'),
|
||||
log_level: 'warn',
|
||||
log_level: LOG_LEVEL,
|
||||
})
|
||||
.on('system.login.device', loginDeviceHandler)
|
||||
.on('system.login.slider', loginSliderHandler)
|
||||
|
@ -101,6 +106,23 @@ export default class OicqClient extends Client {
|
|||
});
|
||||
}
|
||||
|
||||
private onMessage = async (event: PrivateMessageEvent | GroupMessageEvent | DiscussMessageEvent) => {
|
||||
if (event.message_type === 'discuss') return;
|
||||
for (const handler of this.onMessageHandlers) {
|
||||
const res = await handler(event);
|
||||
if (res) return;
|
||||
}
|
||||
};
|
||||
|
||||
public addNewMessageEventHandler(handler: MessageHandler) {
|
||||
this.onMessageHandlers.push(handler);
|
||||
}
|
||||
|
||||
public removeNewMessageEventHandler(handler: MessageHandler) {
|
||||
this.onMessageHandlers.includes(handler) &&
|
||||
this.onMessageHandlers.splice(this.onMessageHandlers.indexOf(handler), 1);
|
||||
}
|
||||
|
||||
public getChat(roomId: number) {
|
||||
if (roomId > 0) {
|
||||
return this.pickFriend(roomId);
|
||||
|
|
|
@ -5,9 +5,11 @@ import ConfigService from '../services/ConfigService';
|
|||
import { config } from '../providers/userConfig';
|
||||
import regExps from '../constants/regExps';
|
||||
import forwardPairs from '../providers/forwardPairs';
|
||||
import { GroupMessageEvent, PrivateMessageEvent } from 'oicq';
|
||||
|
||||
export default class ConfigController {
|
||||
private readonly configService: ConfigService;
|
||||
private readonly createPrivateMessageGroupBlockList = new Map<number, Promise<void>>();
|
||||
|
||||
constructor(private readonly tgBot: Telegram,
|
||||
private readonly tgUser: Telegram,
|
||||
|
@ -15,6 +17,7 @@ export default class ConfigController {
|
|||
this.configService = new ConfigService(tgBot, tgUser, oicq);
|
||||
tgBot.addNewMessageEventHandler(this.handleMessage);
|
||||
tgBot.addNewServiceMessageEventHandler(this.handleServiceMessage);
|
||||
oicq.addNewMessageEventHandler(this.handleQqMessage);
|
||||
this.configService.configCommands();
|
||||
config.workMode === 'personal' && this.configService.setupFilter();
|
||||
}
|
||||
|
@ -69,4 +72,21 @@ export default class ConfigController {
|
|||
pair.tg = await this.tgBot.getChat(message.action.channelId);
|
||||
}
|
||||
};
|
||||
|
||||
private handleQqMessage = async (message: GroupMessageEvent | PrivateMessageEvent) => {
|
||||
if (message.message_type !== 'private') return false;
|
||||
const pair = forwardPairs.find(message.friend);
|
||||
if (pair) return false;
|
||||
// 如果正在创建中,应该阻塞
|
||||
let promise = this.createPrivateMessageGroupBlockList.get(message.from_id);
|
||||
if (promise) {
|
||||
await promise;
|
||||
return false;
|
||||
}
|
||||
// 有未创建转发群的新私聊消息时自动创建
|
||||
promise = this.configService.createGroupAndLink(message.from_id, message.friend.remark || message.friend.nickname, true);
|
||||
this.createPrivateMessageGroupBlockList.set(message.from_id, promise);
|
||||
await promise;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import Telegram from '../client/Telegram';
|
|||
import OicqClient from '../client/OicqClient';
|
||||
import ForwardService from '../services/ForwardService';
|
||||
import forwardPairs from '../providers/forwardPairs';
|
||||
import { DiscussMessageEvent, Friend, Group, GroupMessageEvent, PrivateMessageEvent } from 'oicq';
|
||||
import { Friend, Group, GroupMessageEvent, PrivateMessageEvent } from 'oicq';
|
||||
import db from '../providers/db';
|
||||
import helper from '../helpers/forwardHelper';
|
||||
import { Api } from 'telegram';
|
||||
|
@ -15,19 +15,18 @@ export default class ForwardController {
|
|||
private readonly oicq: OicqClient) {
|
||||
this.forwardService = new ForwardService(tgBot, oicq);
|
||||
forwardPairs.init(oicq, tgBot)
|
||||
.then(() => oicq.on('message', this.onQqMessage))
|
||||
.then(() => oicq.addNewMessageEventHandler(this.onQqMessage))
|
||||
.then(() => tgBot.addNewMessageEventHandler(this.onTelegramMessage));
|
||||
}
|
||||
|
||||
private onQqMessage = async (event: PrivateMessageEvent | GroupMessageEvent | DiscussMessageEvent) => {
|
||||
private onQqMessage = async (event: PrivateMessageEvent | GroupMessageEvent) => {
|
||||
let target: Friend | Group;
|
||||
if (event.message_type === 'private') {
|
||||
target = event.friend;
|
||||
}
|
||||
else if (event.message_type === 'group') {
|
||||
else {
|
||||
target = event.group;
|
||||
}
|
||||
else return;
|
||||
const pair = forwardPairs.find(target);
|
||||
if (!pair) return;
|
||||
const tgMessage = await this.forwardService.forwardFromQq(event, pair);
|
||||
|
|
|
@ -109,7 +109,7 @@ export default class ConfigService {
|
|||
|
||||
// endregion
|
||||
|
||||
private async createGroupAndLink(roomId: number, title?: string) {
|
||||
public async createGroupAndLink(roomId: number, title?: string, silent = false) {
|
||||
this.log.info(`创建群组并关联:${roomId}`);
|
||||
const qEntity = this.oicq.getChat(roomId);
|
||||
if (!title) {
|
||||
|
@ -124,7 +124,7 @@ export default class ConfigService {
|
|||
let isFinish = false;
|
||||
try {
|
||||
// 状态信息
|
||||
const status = await (await this.owner).sendMessage('正在创建 Telegram 群…');
|
||||
const status = !silent && await (await this.owner).sendMessage('正在创建 Telegram 群…');
|
||||
|
||||
// 创建群聊,拿到的是 user 的 chat
|
||||
const chat = await this.tgUser.createChat({
|
||||
|
@ -133,12 +133,12 @@ export default class ConfigService {
|
|||
});
|
||||
|
||||
// 设置管理员
|
||||
await status.edit({ text: '正在设置管理员…' });
|
||||
status && await status.edit({ text: '正在设置管理员…' });
|
||||
await chat.editAdmin(this.tgBot.me.username, true);
|
||||
const chatForBot = await this.tgBot.getChat(chat.id);
|
||||
|
||||
// 添加到 Filter
|
||||
await status.edit({ text: '正在将群添加到文件夹…' });
|
||||
status && await status.edit({ text: '正在将群添加到文件夹…' });
|
||||
this.filter.includePeers.push(utils.getInputPeer(chat));
|
||||
await this.tgUser.updateDialogFilter({
|
||||
id: this.filter.id,
|
||||
|
@ -146,16 +146,16 @@ export default class ConfigService {
|
|||
});
|
||||
|
||||
// 关闭【添加成员】快捷条
|
||||
await status.edit({ text: '正在关闭【添加成员】快捷条…' });
|
||||
status && await status.edit({ text: '正在关闭【添加成员】快捷条…' });
|
||||
await chat.hidePeerSettingsBar();
|
||||
|
||||
// 关联写入数据库
|
||||
await status.edit({ text: '正在写数据库…' });
|
||||
status && await status.edit({ text: '正在写数据库…' });
|
||||
const dbPair = await forwardPairs.add(qEntity, chatForBot);
|
||||
isFinish = true;
|
||||
|
||||
// 更新头像
|
||||
await status.edit({ text: '正在更新头像…' });
|
||||
status && await status.edit({ text: '正在更新头像…' });
|
||||
const avatar = await getAvatar(roomId);
|
||||
const avatarHash = md5B64(avatar);
|
||||
await chatForBot.setProfilePhoto(avatar);
|
||||
|
@ -164,16 +164,18 @@ export default class ConfigService {
|
|||
});
|
||||
|
||||
// 更新关于文本
|
||||
await status.edit({ text: '正在更新关于文本…' });
|
||||
status && await status.edit({ text: '正在更新关于文本…' });
|
||||
await chatForBot.editAbout(await this.getAboutText(qEntity));
|
||||
|
||||
// 完成
|
||||
await status.edit({ text: '正在获取链接…' });
|
||||
const { link } = await chat.getInviteLink();
|
||||
await status.edit({
|
||||
text: '创建完成!',
|
||||
buttons: Button.url('打开', link),
|
||||
});
|
||||
if (status) {
|
||||
await status.edit({ text: '正在获取链接…' });
|
||||
const { link } = await chat.getInviteLink();
|
||||
await status.edit({
|
||||
text: '创建完成!',
|
||||
buttons: Button.url('打开', link),
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
this.log.error('创建群组并关联失败', e);
|
||||
|
|
Loading…
Reference in New Issue