Merge pull request #60 from lixiang810/raincandy

 单向转发
This commit is contained in:
凌莞~(=^▽^=) 2022-10-18 11:40:08 +08:00 committed by GitHub
commit 9b15340ebe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 194 additions and 136 deletions

View File

@ -75,6 +75,8 @@ model ForwardPair {
joinNotice Boolean @default(true)
poke Boolean @default(true)
enable Boolean @default(true)
disableQ2TG Boolean @default(false)
disableTG2Q Boolean @default(false)
@@unique([qqRoomId, instanceId])
@@unique([tgChatId, instanceId])

View File

@ -1,26 +1,28 @@
import { Api } from 'telegram';
import { Api } from "telegram";
const preSetupCommands = [new Api.BotCommand({
command: 'setup',
description: '执行初始化配置',
})];
const preSetupCommands = [
new Api.BotCommand({
command: "setup",
description: "执行初始化配置",
}),
];
// 这里的 group 指群组模式Private 指在与机器人的私聊会话中
const groupPrivateCommands = [
new Api.BotCommand({
command: 'add',
description: '添加新的群转发',
command: "add",
description: "添加新的群转发",
}),
];
const personalPrivateCommands = [
new Api.BotCommand({
command: 'addfriend',
description: '添加新的好友转发',
command: "addfriend",
description: "添加新的好友转发",
}),
new Api.BotCommand({
command: 'addgroup',
description: '添加新的群转发',
command: "addgroup",
description: "添加新的群转发",
}),
];
@ -28,52 +30,56 @@ const personalPrivateCommands = [
const groupPrivateSuperAdminCommands = [
...groupPrivateCommands,
new Api.BotCommand({
command: 'newinstance',
description: '创建一个新的转发机器人实例',
command: "newinstance",
description: "创建一个新的转发机器人实例",
}),
];
const personalPrivateSuperAdminCommands = [
...personalPrivateCommands,
new Api.BotCommand({
command: 'newinstance',
description: '创建一个新的转发机器人实例',
command: "newinstance",
description: "创建一个新的转发机器人实例",
}),
];
// inChat 表示在关联了的转发群组中的命令
const inChatCommands = [
new Api.BotCommand({
command: 'info',
description: '查看本群或选定消息的详情',
command: "info",
description: "查看本群或选定消息的详情",
}),
];
const groupInChatCommands = [
...inChatCommands,
new Api.BotCommand({
command: 'forwardoff',
description: '暂停消息转发',
command: "forwardoff",
description: "暂停消息转发",
}),
new Api.BotCommand({
command: 'forwardon',
description: '恢复消息转发',
command: "forwardon",
description: "恢复消息转发",
}),
new Api.BotCommand({ command: "disableQQForward", description: "停止从QQ转发至TG" }),
new Api.BotCommand({ command: "enableQQForward", description: "恢复从QQ转发至TG" }),
new Api.BotCommand({ command: "disableTGForward", description: "停止从TG转发至QQ" }),
new Api.BotCommand({ command: "enableTGForward", description: "恢复从TG转发至QQ" }),
];
const personalInChatCommands = [
...inChatCommands,
new Api.BotCommand({
command: 'refresh',
description: '刷新头像和简介',
command: "refresh",
description: "刷新头像和简介",
}),
new Api.BotCommand({
command: 'poke',
description: '戳一戳',
command: "poke",
description: "戳一戳",
}),
new Api.BotCommand({
command: 'nick',
description: '获取/设置群名片',
command: "nick",
description: "获取/设置群名片",
}),
];

View File

@ -1,6 +1,6 @@
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import ForwardService from '../services/ForwardService';
import Telegram from "../client/Telegram";
import OicqClient from "../client/OicqClient";
import ForwardService from "../services/ForwardService";
import {
Friend,
FriendPokeEvent,
@ -8,40 +8,43 @@ import {
GroupPokeEvent,
MemberIncreaseEvent,
PrivateMessageEvent,
} from 'oicq';
import db from '../models/db';
import { Api } from 'telegram';
import { getLogger, Logger } from 'log4js';
import Instance from '../models/Instance';
import { getAvatar } from '../utils/urls';
import { CustomFile } from 'telegram/client/uploads';
import forwardHelper from '../helpers/forwardHelper';
} from "oicq";
import db from "../models/db";
import { Api } from "telegram";
import { getLogger, Logger } from "log4js";
import Instance from "../models/Instance";
import { getAvatar } from "../utils/urls";
import { CustomFile } from "telegram/client/uploads";
import forwardHelper from "../helpers/forwardHelper";
export default class ForwardController {
private readonly forwardService: ForwardService;
private readonly log: Logger;
constructor(private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly tgUser: Telegram,
private readonly oicq: OicqClient) {
constructor(
private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly tgUser: Telegram,
private readonly oicq: OicqClient
) {
this.log = getLogger(`ForwardController - ${instance.id}`);
this.forwardService = new ForwardService(this.instance, tgBot, oicq);
oicq.addNewMessageEventHandler(this.onQqMessage);
oicq.on('notice.group.increase', this.onQqGroupMemberIncrease);
oicq.on('notice.friend.poke', this.onQqPoke);
oicq.on('notice.group.poke', this.onQqPoke);
oicq.on("notice.group.increase", this.onQqGroupMemberIncrease);
oicq.on("notice.friend.poke", this.onQqPoke);
oicq.on("notice.group.poke", this.onQqPoke);
tgBot.addNewMessageEventHandler(this.onTelegramMessage);
tgBot.addEditedMessageEventHandler(this.onTelegramMessage);
instance.workMode === 'group' && tgBot.addChannelParticipantEventHandler(this.onTelegramParticipant);
instance.workMode === "group" && tgBot.addChannelParticipantEventHandler(this.onTelegramParticipant);
}
private onQqMessage = async (event: PrivateMessageEvent | GroupMessageEvent) => {
try {
const target = event.message_type === 'private' ? event.friend : event.group;
const target = event.message_type === "private" ? event.friend : event.group;
const pair = this.instance.forwardPairs.find(target);
if (!pair) return;
if (!pair.enable) return;
if (pair.disableQ2TG) return;
const tgMessage = await this.forwardService.forwardFromQq(event, pair);
if (tgMessage) {
// 更新数据库
@ -60,9 +63,8 @@ export default class ForwardController {
},
});
}
}
catch (e) {
this.log.error('处理 QQ 消息时遇到问题', e);
} catch (e) {
this.log.error("处理 QQ 消息时遇到问题", e);
}
};
@ -72,6 +74,7 @@ export default class ForwardController {
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return false;
if (!pair.enable) return;
if (pair.disableTG2Q) return;
const qqMessagesSent = await this.forwardService.forwardFromTelegram(message, pair);
if (qqMessagesSent) {
// 更新数据库
@ -92,9 +95,8 @@ export default class ForwardController {
});
}
}
}
catch (e) {
this.log.error('处理 Telegram 消息时遇到问题', e);
} catch (e) {
this.log.error("处理 Telegram 消息时遇到问题", e);
}
};
@ -104,13 +106,12 @@ export default class ForwardController {
if (!pair?.joinNotice) return false;
const avatar = await getAvatar(event.user_id);
await pair.tg.sendMessage({
file: new CustomFile('avatar.png', avatar.length, '', avatar),
file: new CustomFile("avatar.png", avatar.length, "", avatar),
message: `<b>${event.nickname}</b> (<code>${event.user_id}</code>) <i>加入了本群</i>`,
silent: true,
});
}
catch (e) {
this.log.error('处理 QQ 群成员增加事件时遇到问题', e);
} catch (e) {
this.log.error("处理 QQ 群成员增加事件时遇到问题", e);
}
};
@ -118,48 +119,44 @@ export default class ForwardController {
try {
const pair = this.instance.forwardPairs.find(event.channelId);
if (!pair?.joinNotice) return false;
if (!(event.newParticipant instanceof Api.ChannelParticipantAdmin)
&& !(event.newParticipant instanceof Api.ChannelParticipantCreator)
&& !(event.newParticipant instanceof Api.ChannelParticipant))
if (
!(event.newParticipant instanceof Api.ChannelParticipantAdmin) &&
!(event.newParticipant instanceof Api.ChannelParticipantCreator) &&
!(event.newParticipant instanceof Api.ChannelParticipant)
)
return false;
const member = await this.tgBot.getChat(event.newParticipant.userId);
await pair.qq.sendMsg(`${forwardHelper.getUserDisplayName(member.entity)} 加入了本群`);
}
catch (e) {
this.log.error('处理 TG 群成员增加事件时遇到问题', e);
} catch (e) {
this.log.error("处理 TG 群成员增加事件时遇到问题", e);
}
};
private onQqPoke = async (event: FriendPokeEvent | GroupPokeEvent) => {
const target = event.notice_type === 'friend' ? event.friend : event.group;
const target = event.notice_type === "friend" ? event.friend : event.group;
const pair = this.instance.forwardPairs.find(target);
if (!pair?.poke) return;
let operatorName: string, targetName: string;
if (target instanceof Friend) {
if (event.operator_id === target.user_id) {
operatorName = target.remark || target.nickname;
}
else {
operatorName = '你';
} else {
operatorName = "你";
}
if (event.operator_id === event.target_id) {
targetName = '自己';
}
else if (event.target_id === target.user_id) {
targetName = "自己";
} else if (event.target_id === target.user_id) {
targetName = target.remark || target.nickname;
} else {
targetName = "你";
}
else {
targetName = '你';
}
}
else {
} else {
const operator = target.pickMember(event.operator_id);
await operator.renew();
operatorName = operator.card || operator.info.nickname;
if (event.operator_id === event.target_id) {
targetName = '自己';
}
else {
targetName = "自己";
} else {
const targetUser = target.pickMember(event.target_id);
await targetUser.renew();
targetName = targetUser.card || targetUser.info.nickname;

View File

@ -1,18 +1,20 @@
import InChatCommandsService from '../services/InChatCommandsService';
import { getLogger, Logger } from 'log4js';
import Instance from '../models/Instance';
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import { Api } from 'telegram';
import { Group } from 'oicq';
import InChatCommandsService from "../services/InChatCommandsService";
import { getLogger, Logger } from "log4js";
import Instance from "../models/Instance";
import Telegram from "../client/Telegram";
import OicqClient from "../client/OicqClient";
import { Api } from "telegram";
import { Group } from "oicq";
export default class InChatCommandsController {
private readonly service: InChatCommandsService;
private readonly log: Logger;
constructor(private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly oicq: OicqClient) {
constructor(
private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly oicq: OicqClient
) {
this.log = getLogger(`InChatCommandsController - ${instance.id}`);
this.service = new InChatCommandsService(instance, tgBot, oicq);
tgBot.addNewMessageEventHandler(this.onTelegramMessage);
@ -20,39 +22,55 @@ export default class InChatCommandsController {
private onTelegramMessage = async (message: Api.Message) => {
if (!message.message) return;
const messageParts = message.message.split(' ');
if (!messageParts.length || !messageParts[0].startsWith('/')) return;
const messageParts = message.message.split(" ");
if (!messageParts.length || !messageParts[0].startsWith("/")) return;
let command: string = messageParts.shift();
const params = messageParts.join(' ');
if (command.includes('@')) {
const params = messageParts.join(" ");
if (command.includes("@")) {
let target: string;
[command, target] = command.split('@');
[command, target] = command.split("@");
if (target !== this.tgBot.me.username) return false;
}
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return false;
switch (command) {
case '/info':
case "/info":
await this.service.info(message, pair);
return true;
case '/poke':
case "/poke":
await this.service.poke(message, pair);
return true;
case '/forwardoff':
case "/forwardoff":
pair.enable = false;
await message.reply({ message: '转发已禁用' });
await message.reply({ message: "转发已禁用" });
return true;
case '/forwardon':
case "/forwardon":
pair.enable = true;
await message.reply({ message: '转发已启用' });
await message.reply({ message: "转发已启用" });
return true;
case '/refresh':
if (this.instance.workMode !== 'personal' || !message.senderId?.eq(this.instance.owner)) return false;
case "/disableQQForward":
pair.disableQ2TG = true;
await message.reply({ message: "QQ->TG已禁用" });
return true;
case "/enableQQForward":
pair.disableQ2TG = false;
await message.reply({ message: "QQ->TG已启用" });
return true;
case "/disableTGForward":
pair.disableTG2Q = true;
await message.reply({ message: "TG->QQ已禁用" });
return true;
case "/enableTGForward":
pair.disableTG2Q = false;
await message.reply({ message: "TG->QQ已启用" });
return true;
case "/refresh":
if (this.instance.workMode !== "personal" || !message.senderId?.eq(this.instance.owner)) return false;
await pair.updateInfo();
await message.reply({ message: '<i>刷新成功</i>' });
await message.reply({ message: "<i>刷新成功</i>" });
return true;
case '/nick':
if (this.instance.workMode !== 'personal' || !message.senderId?.eq(this.instance.owner)) return false;
case "/nick":
if (this.instance.workMode !== "personal" || !message.senderId?.eq(this.instance.owner)) return false;
if (!(pair.qq instanceof Group)) return;
if (!params) {
await message.reply({
@ -62,7 +80,7 @@ export default class InChatCommandsController {
}
const result = await pair.qq.setCard(this.instance.qqUin, params);
await message.reply({
message: '设置' + (result ? '成功' : '失败'),
message: "设置" + (result ? "成功" : "失败"),
});
return true;
}

View File

@ -1,21 +1,24 @@
import { Friend, Group } from 'oicq';
import TelegramChat from '../client/TelegramChat';
import db from './db';
import { getLogger } from 'log4js';
import { getAvatar } from '../utils/urls';
import { md5 } from '../utils/hashing';
import getAboutText from '../utils/getAboutText';
import { getLogger } from "log4js";
import { Friend, Group } from "oicq";
import TelegramChat from "../client/TelegramChat";
import getAboutText from "../utils/getAboutText";
import { md5 } from "../utils/hashing";
import { getAvatar } from "../utils/urls";
import db from "./db";
const log = getLogger('ForwardPair');
const log = getLogger("ForwardPair");
export class Pair {
constructor(public readonly qq: Friend | Group,
private _tg: TelegramChat,
public dbId: number,
private _joinNotice: boolean,
private _poke: boolean,
private _enable: boolean) {
}
constructor(
public readonly qq: Friend | Group,
private _tg: TelegramChat,
public dbId: number,
private _joinNotice: boolean,
private _poke: boolean,
private _enable: boolean,
private _disableQ2TG: boolean,
private _disableTG2Q: boolean
) {}
// 更新 TG 群组的头像和简介
public async updateInfo() {
@ -51,10 +54,11 @@ export class Pair {
set tg(value: TelegramChat) {
this._tg = value;
db.forwardPair.update({
where: { id: this.dbId },
data: { tgChatId: Number(value.id) },
})
db.forwardPair
.update({
where: { id: this.dbId },
data: { tgChatId: Number(value.id) },
})
.then(() => log.info(`出现了到超级群组的转换: ${value.id}`));
}
@ -64,10 +68,11 @@ export class Pair {
set joinNotice(value) {
this._joinNotice = value;
db.forwardPair.update({
where: { id: this.dbId },
data: { joinNotice: value },
})
db.forwardPair
.update({
where: { id: this.dbId },
data: { joinNotice: value },
})
.then(() => 0);
}
@ -77,10 +82,11 @@ export class Pair {
set poke(value) {
this._poke = value;
db.forwardPair.update({
where: { id: this.dbId },
data: { poke: value },
})
db.forwardPair
.update({
where: { id: this.dbId },
data: { poke: value },
})
.then(() => 0);
}
@ -90,10 +96,39 @@ export class Pair {
set enable(value) {
this._enable = value;
db.forwardPair.update({
where: { id: this.dbId },
data: { enable: value },
})
db.forwardPair
.update({
where: { id: this.dbId },
data: { enable: value },
})
.then(() => 0);
}
get disableQ2TG() {
return this._disableQ2TG;
}
set disableQ2TG(value) {
this._disableQ2TG = value;
db.forwardPair
.update({
where: { id: this.dbId },
data: { disableQ2TG: value },
})
.then(() => 0);
}
get disableTG2Q() {
return this._disableTG2Q;
}
set disableTG2Q(value) {
this._disableTG2Q = value;
db.forwardPair
.update({
where: { id: this.dbId },
data: { disableTG2Q: value },
})
.then(() => 0);
}
}