Compare commits

...

20 Commits

Author SHA1 Message Date
Nofated095 134a21b279 patch(delete tgUser function) 2024-02-17 08:04:39 +08:00
Nofated095 7a3ddc4309 Merge branch 'rainbowcat' of github.com:clansty/Q2TG into rainbowcat 2024-02-17 07:58:08 +08:00
Clansty e8e91c81ac
fix: pair 没有判空 2024-02-12 23:10:22 +08:00
Clansty 6290edf0b0
feat: 转发 tg 中其他 bot 的消息 2024-02-12 23:08:33 +08:00
Clansty fdbfda72d4
feat: /q 后自动在 tg pin 原消息,在 QQ 将原消息设为精华 2024-02-12 22:38:55 +08:00
Clansty d2a60b3cd0
fix: 通过回测解决 Rich Header 抽风无法加载时出现没有发送者信息的消息 2024-02-09 16:00:14 +08:00
Clansty f627a94e69
Merge remote-tracking branch 'origin/rainbowcat' into rainbowcat 2024-02-09 14:54:42 +08:00
Clansty f1552b1f2e
chore: 收到加群申请时,显示群头像而不是邀请人的头像 2024-02-09 14:54:23 +08:00
凌莞~(=^▽^=) 9f653e449f
Merge pull request #198 from clansty/dependabot/npm_and_yarn/prisma-5.9.1
chore(deps): bump prisma from 5.8.0 to 5.9.1
2024-02-09 13:10:21 +08:00
dependabot[bot] 7f6a301f6e
chore(deps): bump prisma from 5.8.0 to 5.9.1
Bumps [prisma](https://github.com/prisma/prisma/tree/HEAD/packages/cli) from 5.8.0 to 5.9.1.
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/5.9.1/packages/cli)

---
updated-dependencies:
- dependency-name: prisma
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 05:10:10 +00:00
凌莞~(=^▽^=) cfb02ba050
Merge pull request #199 from clansty/dependabot/npm_and_yarn/prisma/client-5.9.1
chore(deps): bump @prisma/client from 5.8.0 to 5.9.1
2024-02-09 13:09:08 +08:00
dependabot[bot] 769b047f6d
chore(deps): bump @prisma/client from 5.8.0 to 5.9.1
Bumps [@prisma/client](https://github.com/prisma/prisma/tree/HEAD/packages/client) from 5.8.0 to 5.9.1.
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/5.9.1/packages/client)

---
updated-dependencies:
- dependency-name: "@prisma/client"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 05:08:53 +00:00
凌莞~(=^▽^=) e551d747e8
Merge pull request #202 from clansty/dependabot/npm_and_yarn/types/node-20.11.17
chore(deps-dev): bump @types/node from 20.11.5 to 20.11.17
2024-02-09 13:08:18 +08:00
凌莞~(=^▽^=) ffd91deb92
Merge pull request #189 from clansty/dependabot/npm_and_yarn/dotenv-16.4.1
chore(deps): bump dotenv from 16.4.0 to 16.4.1
2024-02-09 13:08:08 +08:00
凌莞~(=^▽^=) fc12b92b9f
Merge pull request #191 from clansty/dependabot/npm_and_yarn/axios-1.6.7
chore(deps): bump axios from 1.6.5 to 1.6.7
2024-02-09 13:07:56 +08:00
dependabot[bot] e94aad6af6
chore(deps-dev): bump @types/node from 20.11.5 to 20.11.17
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.11.5 to 20.11.17.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 03:00:23 +00:00
Clansty 4df30e8705
Merge remote-tracking branch 'origin/rainbowcat' into rainbowcat 2024-02-04 21:25:15 +08:00
Clansty 000da5c93f
fix: 在私聊时不应该显示 RichHeader 2024-02-04 21:24:44 +08:00
dependabot[bot] dff0364d85
chore(deps): bump dotenv from 16.4.0 to 16.4.1
Bumps [dotenv](https://github.com/motdotla/dotenv) from 16.4.0 to 16.4.1.
- [Changelog](https://github.com/motdotla/dotenv/blob/master/CHANGELOG.md)
- [Commits](https://github.com/motdotla/dotenv/compare/v16.4.0...v16.4.1)

---
updated-dependencies:
- dependency-name: dotenv
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-01 09:23:09 +00:00
dependabot[bot] eaa46d0d00
chore(deps): bump axios from 1.6.5 to 1.6.7
Bumps [axios](https://github.com/axios/axios) from 1.6.5 to 1.6.7.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.6.5...v1.6.7)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-26 02:59:21 +00:00
14 changed files with 150 additions and 92 deletions

2
.gitignore vendored
View File

@ -728,7 +728,7 @@ Network Trash Folder
Temporary Items
.apdisk
data/
data
config.yaml
build
.yarn/*

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -18,20 +18,20 @@
"@types/dockerode": "^3.3.23",
"@types/fluent-ffmpeg": "^2.1.24",
"@types/lodash": "^4.14.202",
"@types/node": "^20.11.5",
"@types/node": "^20.11.17",
"@types/prompts": "^2.4.9",
"tsx": "^4.7.0",
"typescript": "^5.3.3"
},
"dependencies": {
"@prisma/client": "5.8.0",
"axios": "^1.6.5",
"@prisma/client": "5.9.1",
"axios": "^1.6.7",
"baidu-aip-sdk": "^4.16.15",
"big-integer": "^1.6.52",
"cli-progress": "^3.11.2",
"date-and-time": "^3.1.1",
"dockerode": "^4.0.2",
"dotenv": "^16.4.0",
"dotenv": "^16.4.1",
"eviltransform": "^0.2.2",
"file-type": "^19.0.0",
"fluent-ffmpeg": "^2.1.2",
@ -40,7 +40,7 @@
"lodash": "^4.17.21",
"log4js": "^6.6.1",
"nodejs-base64": "^2.0.0",
"prisma": "5.8.0",
"prisma": "5.9.1",
"prompts": "^2.4.2",
"quote-api": "https://github.com/Clansty/quote-api/archive/014b21138afbbe0e12c91b00561414b1e851fc0f.tar.gz",
"sharp": "^0.33.2",

View File

@ -6,11 +6,11 @@ settings:
dependencies:
'@prisma/client':
specifier: 5.8.0
version: 5.8.0(prisma@5.8.0)
specifier: 5.9.1
version: 5.9.1(prisma@5.9.1)
axios:
specifier: ^1.6.5
version: 1.6.5
specifier: ^1.6.7
version: 1.6.7
baidu-aip-sdk:
specifier: ^4.16.15
version: 4.16.15
@ -27,8 +27,8 @@ dependencies:
specifier: ^4.0.2
version: 4.0.2
dotenv:
specifier: ^16.4.0
version: 16.4.0
specifier: ^16.4.1
version: 16.4.1
eviltransform:
specifier: ^0.2.2
version: 0.2.2
@ -54,8 +54,8 @@ dependencies:
specifier: ^2.0.0
version: 2.0.0
prisma:
specifier: 5.8.0
version: 5.8.0
specifier: 5.9.1
version: 5.9.1
prompts:
specifier: ^2.4.2
version: 2.4.2
@ -70,7 +70,7 @@ dependencies:
version: 0.2.2
telegram:
specifier: https://github.com/clansty/gramjs/releases/download/2.19.10%2Brevert_media/telegram-2.19.10.tgz
version: '@github.com/clansty/gramjs/releases/download/2.19.10%25252Brevert_media/telegram-2.19.10.tgz'
version: '@github.com/clansty/gramjs/releases/download/2.19.10%25252525252Brevert_media/telegram-2.19.10.tgz'
tmp-promise:
specifier: ^3.0.3
version: 3.0.3
@ -101,8 +101,8 @@ devDependencies:
specifier: ^4.14.202
version: 4.14.202
'@types/node':
specifier: ^20.11.5
version: 20.11.5
specifier: ^20.11.17
version: 20.11.17
'@types/prompts':
specifier: ^2.4.9
version: 2.4.9
@ -895,8 +895,8 @@ packages:
- supports-color
dev: false
/@prisma/client@5.8.0(prisma@5.8.0):
resolution: {integrity: sha512-QxO6C4MaA/ysTIbC+EcAH1aX/YkpymhXtO6zPdk+FvA7+59tNibIYpd+7koPdViLg2iKES4ojsxWNUGNJaEcbA==}
/@prisma/client@5.9.1(prisma@5.9.1):
resolution: {integrity: sha512-caSOnG4kxcSkhqC/2ShV7rEoWwd3XrftokxJqOCMVvia4NYV/TPtJlS9C2os3Igxw/Qyxumj9GBQzcStzECvtQ==}
engines: {node: '>=16.13'}
requiresBuild: true
peerDependencies:
@ -905,39 +905,39 @@ packages:
prisma:
optional: true
dependencies:
prisma: 5.8.0
prisma: 5.9.1
dev: false
/@prisma/debug@5.8.0:
resolution: {integrity: sha512-ZqPpkvbovu/kQJ1bvy57NO4dw97fpQGcbQSCtsqlwSE1UNKJP75R3BKxdznk8ZPMY+GJdMRetWNv4oAvSbWn8Q==}
/@prisma/debug@5.9.1:
resolution: {integrity: sha512-yAHFSFCg8KVoL0oRUno3m60GAjsUKYUDkQ+9BA2X2JfVR3kRVSJFc/GpQ2fSORi4pSHZR9orfM4UC9OVXIFFTA==}
dev: false
/@prisma/engines-version@5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848:
resolution: {integrity: sha512-cXcoVweYbnv8xRfkWq9oj8BECOdzHUazrSpYCa0ehp5TNz4l5Spa8jbq/VROCTzj3ZncH5D9Q2TmySYTOUeKlw==}
/@prisma/engines-version@5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64:
resolution: {integrity: sha512-HFl7275yF0FWbdcNvcSRbbu9JCBSLMcurYwvWc8WGDnpu7APxQo2ONtZrUggU3WxLxUJ2uBX+0GOFIcJeVeOOQ==}
dev: false
/@prisma/engines@5.8.0:
resolution: {integrity: sha512-Qhqm9WWLujNEC13AuZlUO14SQ15tNLe5puaz+tOk7UqINqJ3PtqMmuSuzomiw2diGVqZ+HYiSQzlR3+pPucVHA==}
/@prisma/engines@5.9.1:
resolution: {integrity: sha512-gkdXmjxQ5jktxWNdDA5aZZ6R8rH74JkoKq6LD5mACSvxd2vbqWeWIOV0Py5wFC8vofOYShbt6XUeCIUmrOzOnQ==}
requiresBuild: true
dependencies:
'@prisma/debug': 5.8.0
'@prisma/engines-version': 5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848
'@prisma/fetch-engine': 5.8.0
'@prisma/get-platform': 5.8.0
'@prisma/debug': 5.9.1
'@prisma/engines-version': 5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64
'@prisma/fetch-engine': 5.9.1
'@prisma/get-platform': 5.9.1
dev: false
/@prisma/fetch-engine@5.8.0:
resolution: {integrity: sha512-1CAuE+JoYsPNggMEn6qk0zos06Uc9bYZBJ0VBPHD6R7REL05614koAbOCmn52IaYz3nobb7f25hqW6AY7rLkIw==}
/@prisma/fetch-engine@5.9.1:
resolution: {integrity: sha512-l0goQOMcNVOJs1kAcwqpKq3ylvkD9F04Ioe1oJoCqmz05mw22bNAKKGWuDd3zTUoUZr97va0c/UfLNru+PDmNA==}
dependencies:
'@prisma/debug': 5.8.0
'@prisma/engines-version': 5.8.0-37.0a83d8541752d7582de2ebc1ece46519ce72a848
'@prisma/get-platform': 5.8.0
'@prisma/debug': 5.9.1
'@prisma/engines-version': 5.9.0-32.23fdc5965b1e05fc54e5f26ed3de66776b93de64
'@prisma/get-platform': 5.9.1
dev: false
/@prisma/get-platform@5.8.0:
resolution: {integrity: sha512-Nk3rhTFZ1LYkFZJnpSvQcLPCaBWgJQfteHII6UEENOOkYlmP0k3FuswND54tzzEr4qs39wOdV9pbXKX9U2lv7A==}
/@prisma/get-platform@5.9.1:
resolution: {integrity: sha512-6OQsNxTyhvG+T2Ksr8FPFpuPeL4r9u0JF0OZHUBI/Uy9SS43sPyAIutt4ZEAyqWQt104ERh70EZedkHZKsnNbg==}
dependencies:
'@prisma/debug': 5.8.0
'@prisma/debug': 5.9.1
dev: false
/@tokenizer/token@0.3.0:
@ -952,7 +952,7 @@ packages:
/@types/cli-progress@3.11.5:
resolution: {integrity: sha512-D4PbNRbviKyppS5ivBGyFO29POlySLmA2HyUFE4p5QGazAMM3CwkKWcvTl8gvElSuxRh6FPKL8XmidX873ou4g==}
dependencies:
'@types/node': 20.11.5
'@types/node': 20.11.17
dev: true
/@types/date-and-time@3.0.3:
@ -965,7 +965,7 @@ packages:
/@types/docker-modem@3.0.6:
resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==}
dependencies:
'@types/node': 20.11.5
'@types/node': 20.11.17
'@types/ssh2': 1.11.18
dev: true
@ -973,13 +973,13 @@ packages:
resolution: {integrity: sha512-Lz5J+NFgZS4cEVhquwjIGH4oQwlVn2h7LXD3boitujBnzOE5o7s9H8hchEjoDK2SlRsJTogdKnQeiJgPPKLIEw==}
dependencies:
'@types/docker-modem': 3.0.6
'@types/node': 20.11.5
'@types/node': 20.11.17
dev: true
/@types/fluent-ffmpeg@2.1.24:
resolution: {integrity: sha512-g5oQO8Jgi2kFS3tTub7wLvfLztr1s8tdXmRd8PiL/hLMLzTIAyMR2sANkTggM/rdEDAg3d63nYRRVepwBiCw5A==}
dependencies:
'@types/node': 20.11.5
'@types/node': 20.11.17
dev: true
/@types/lodash@4.14.202:
@ -996,8 +996,8 @@ packages:
undici-types: 5.26.5
dev: true
/@types/node@20.11.5:
resolution: {integrity: sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w==}
/@types/node@20.11.17:
resolution: {integrity: sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==}
dependencies:
undici-types: 5.26.5
dev: true
@ -1005,7 +1005,7 @@ packages:
/@types/prompts@2.4.9:
resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==}
dependencies:
'@types/node': 20.11.5
'@types/node': 20.11.17
kleur: 3.0.3
dev: true
@ -1139,8 +1139,8 @@ packages:
resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==}
dev: false
/axios@1.6.5:
resolution: {integrity: sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==}
/axios@1.6.7:
resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==}
dependencies:
follow-redirects: 1.15.4
form-data: 4.0.0
@ -1652,8 +1652,8 @@ packages:
domhandler: 4.3.1
dev: false
/dotenv@16.4.0:
resolution: {integrity: sha512-WvImr5kpN5NGNn7KaDjJnLTh5rDVLZiDf/YLA8T1ZEZEBZNEDOE+mnkS0PVjPax8ZxBP5zC5SLMB3/9VV5de9g==}
/dotenv@16.4.1:
resolution: {integrity: sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==}
engines: {node: '>=12'}
dev: false
@ -2185,7 +2185,7 @@ packages:
resolution: {integrity: sha512-+Whg6gcxomNshRhij3vuEnjaO/8ODAzl3ZVda6KKwZtWTwuD23iX4pR57Kv7+VGw6Lp5fEGF6hjSxPHw9Rvqcg==}
engines: {node: '>= v14'}
dependencies:
axios: 1.6.5
axios: 1.6.7
log4js: 6.9.1
long: 4.0.0
pngjs: 6.0.0
@ -2908,13 +2908,13 @@ packages:
engines: {node: '>=12.13.0'}
dev: false
/prisma@5.8.0:
resolution: {integrity: sha512-hDKoEqPt2qEUTH5yGO3l27CBnPtwvte0CGMKrpCr9+/A919JghfqJ3qgCGgMbOwdkXUOzdho0RH9tyUF3UhpMw==}
/prisma@5.9.1:
resolution: {integrity: sha512-Hy/8KJZz0ELtkw4FnG9MS9rNWlXcJhf98Z2QMqi0QiVMoS8PzsBkpla0/Y5hTlob8F3HeECYphBjqmBxrluUrQ==}
engines: {node: '>=16.13'}
hasBin: true
requiresBuild: true
dependencies:
'@prisma/engines': 5.8.0
'@prisma/engines': 5.9.1
dev: false
/probe-image-size@7.2.3:
@ -3903,7 +3903,7 @@ packages:
- utf-8-validate
dev: false
'@github.com/clansty/gramjs/releases/download/2.19.10%25252Brevert_media/telegram-2.19.10.tgz':
'@github.com/clansty/gramjs/releases/download/2.19.10%25252525252Brevert_media/telegram-2.19.10.tgz':
resolution: {tarball: https://github.com/clansty/gramjs/releases/download/2.19.10%2Brevert_media/telegram-2.19.10.tgz}
name: telegram
version: 2.19.10

View File

@ -31,6 +31,11 @@ export default class TelegramChat {
return await this.client.sendMessage(this.entity, params);
}
public async getMessage(params: Parameters<typeof this.client.getMessages>[1]) {
const messages = await this.client.getMessages(this.entity, params);
return messages[0];
}
public async sendSelfDestructingPhoto(params: SendMessageParams, photo: CustomFile, ttlSeconds: number) {
// @ts-ignore 定义不好好写的?你家 `FileLike` 明明可以是 `TypeInputMedia`
params.file = new Api.InputMediaUploadedPhoto({

View File

@ -7,6 +7,8 @@ enum flags {
NO_AUTO_CREATE_PM = 1 << 5,
COLOR_EMOJI_PREFIX = 1 << 6,
RICH_HEADER = 1 << 7,
NO_QUOTE_PIN = 1 << 8,
NO_FORWARD_OTHER_BOT = 1 << 9,
}
export default flags;

View File

@ -17,7 +17,6 @@ import { getAvatar } from '../utils/urls';
import { CustomFile } from 'telegram/client/uploads';
import forwardHelper from '../helpers/forwardHelper';
import helper from '../helpers/forwardHelper';
import ZincSearch from 'zincsearch-node';
import flags from '../constants/flags';
export default class ForwardController {
@ -36,6 +35,7 @@ export default class ForwardController {
oicq.on('notice.friend.poke', this.onQqPoke);
oicq.on('notice.group.poke', this.onQqPoke);
tgBot.addNewMessageEventHandler(this.onTelegramMessage);
tgUser.addNewMessageEventHandler(this.onTelegramUserMessage);
tgBot.addEditedMessageEventHandler(this.onTelegramMessage);
instance.workMode === 'group' && tgBot.addChannelParticipantEventHandler(this.onTelegramParticipant);
}
@ -92,10 +92,17 @@ export default class ForwardController {
}
};
private onTelegramMessage = async (message: Api.Message) => {
private onTelegramUserMessage = async (message: Api.Message) => {
if (!('bot' in message.sender) || !message.sender.bot) return;
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return;
if ((pair.flags | this.instance.flags) & flags.NO_FORWARD_OTHER_BOT) return;
await this.onTelegramMessage(message, pair);
};
private onTelegramMessage = async (message: Api.Message, pair = this.instance.forwardPairs.find(message.chat)) => {
try {
if (message.senderId?.eq(this.instance.botMe.id)) return true;
const pair = this.instance.forwardPairs.find(message.chat);
if (!pair) return false;
if ((pair.flags | this.instance.flags) & flags.DISABLE_TG2Q) return;
const qqMessagesSent = await this.forwardService.forwardFromTelegram(message, pair);

View File

@ -6,7 +6,7 @@ import { GroupMessageEvent, MiraiElem, PrivateMessageEvent } from 'icqq';
export default class {
constructor(private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly tgUser: Telegram,
// private readonly tgUser: Telegram,
private readonly qqBot: OicqClient) {
qqBot.addNewMessageEventHandler(this.onQqMessage);
}

View File

@ -2,7 +2,7 @@ import Instance from '../models/Instance';
import Telegram from '../client/Telegram';
import OicqClient from '../client/OicqClient';
import { getLogger, Logger } from 'log4js';
import { GroupMessageEvent, PrivateMessageEvent } from 'icqq';
import { Group, GroupMessageEvent, PrivateMessageEvent } from 'icqq';
import { Api } from 'telegram';
import quotly from 'quote-api/methods/generate.js';
import { CustomFile } from 'telegram/client/uploads';
@ -13,6 +13,7 @@ import { getAvatarUrl } from '../utils/urls';
import convert from '../helpers/convert';
import { Pair } from '../models/Pair';
import env from '../models/env';
import flags from '../constants/flags';
export default class {
private readonly log: Logger;
@ -55,16 +56,14 @@ export default class {
this.log.error('找不到 sourceMessage');
return true;
}
setTimeout(async () => {
// 异步发送,为了让 /q 先到达
try {
await this.sendQuote(pair, sourceMessage);
}
catch (e) {
this.log.error(e);
await event.reply(e.toString(), true);
}
}, 50);
if (!((pair.flags | this.instance.flags) & flags.NO_QUOTE_PIN)) {
this.pinMessageOnBothSide(pair, sourceMessage).then();
}
// 异步发送,为了让 /q 先到达
this.sendQuote(pair, sourceMessage).catch(async e => {
this.log.error(e);
await event.reply(e.toString(), true);
});
};
private onTelegramMessage = async (message: Api.Message) => {
@ -91,22 +90,39 @@ export default class {
this.log.error('找不到 sourceMessage');
return true;
}
setTimeout(async () => {
try {
await this.sendQuote(pair, sourceMessage);
}
catch (e) {
this.log.error(e);
await message.reply({
message: e.toString(),
});
}
}, 50);
if (!((pair.flags | this.instance.flags) & flags.NO_QUOTE_PIN)) {
this.pinMessageOnBothSide(pair, sourceMessage).then();
}
// 异步发送,为了让 /q 先到达
this.sendQuote(pair, sourceMessage).catch(async e => {
this.log.error(e);
await message.reply({
message: e.toString(),
});
});
// 个人模式下,/q 这条消息不转发到 QQ怪话图只有自己可见
if (this.instance.workMode === 'personal') return true;
};
private async pinMessageOnBothSide(pair: Pair, sourceMessage: Awaited<ReturnType<typeof db.message.findFirst>>) {
if (pair.qq instanceof Group) {
try {
await pair.qq.addEssence(sourceMessage.seq, Number(sourceMessage.rand));
}
catch (e) {
this.log.warn('无法添加精华消息,群:', pair.qqRoomId, e);
}
}
try {
const tgMessage = await pair.tg.getMessage({ ids: sourceMessage.tgMsgId });
await tgMessage.pin({ notify: false, pmOneSide: false });
}
catch (e) {
this.log.warn('无法置顶消息,群:', pair.tgId, '消息 ID', sourceMessage.tgMsgId, e);
}
}
private async genQuote(message: Message) {
const GROUP_ANONYMOUS_BOT = 1087968824n;

View File

@ -20,9 +20,10 @@ export default class RequestController {
private handleRequest = async (event: FriendRequestEvent | GroupInviteEvent) => {
this.log.info(`收到申请:${event.nickname} (${event.user_id})`);
const avatar = await getAvatar(event.user_id);
let avatar: Buffer;
let messageText = '';
if (event.request_type === 'friend') {
avatar = await getAvatar(event.user_id);
messageText = `收到好友申请\n` +
`<b>昵称:</b>${event.nickname}\n` +
`<b>账号:</b><code>${event.user_id}</code>\n` +
@ -32,6 +33,7 @@ export default class RequestController {
`<b>附言:</b>${event.comment}`;
}
else {
avatar = await getAvatar(-event.group_id);
messageText = `收到加群邀请\n` +
`<b>邀请人:</b>${event.nickname} (<code>${event.user_id}</code>)\n` +
`<b>群名称:</b>${event.group_name}\n` +

View File

@ -18,7 +18,7 @@ export default class ForwardPairs {
}
// 在 forwardController 创建时初始化
private async init(oicq: OicqClient, tgBot: Telegram) {
private async init(oicq: OicqClient, tgBot: Telegram, tgUser: Telegram) {
const dbValues = await db.forwardPair.findMany({
where: { instanceId: this.instanceId },
});
@ -26,8 +26,9 @@ export default class ForwardPairs {
try {
const qq = oicq.getChat(Number(i.qqRoomId));
const tg = await tgBot.getChat(Number(i.tgChatId));
if (qq && tg) {
this.pairs.push(new Pair(qq, tg, i.id, i.flags));
const tgUserChat = await tgUser.getChat(Number(i.tgChatId));
if (qq && tg && tgUserChat) {
this.pairs.push(new Pair(qq, tg, tgUserChat, i.id, i.flags));
}
}
catch (e) {
@ -36,13 +37,13 @@ export default class ForwardPairs {
}
}
public static async load(instanceId: number, oicq: OicqClient, tgBot: Telegram) {
public static async load(instanceId: number, oicq: OicqClient, tgBot: Telegram, tgUser: Telegram) {
const instance = new this(instanceId);
await instance.init(oicq, tgBot);
await instance.init(oicq, tgBot, tgUser);
return instance;
}
public async add(qq: Friend | Group, tg: TelegramChat) {
public async add(qq: Friend | Group, tg: TelegramChat, tgUser: TelegramChat) {
const dbEntry = await db.forwardPair.create({
data: {
qqRoomId: qq instanceof Friend ? qq.user_id : -qq.group_id,
@ -50,7 +51,7 @@ export default class ForwardPairs {
instanceId: this.instanceId,
},
});
this.pairs.push(new Pair(qq, tg, dbEntry.id, dbEntry.flags));
this.pairs.push(new Pair(qq, tg, tgUser, dbEntry.id, dbEntry.flags));
return dbEntry;
}

View File

@ -11,11 +11,12 @@ const log = getLogger('ForwardPair');
export class Pair {
// 群成员的 tg 账号对应它对应的 QQ 账号获取到的 Group 对象
// 只有群组模式有效
public readonly instanceMapForTg = {} as { [tgUserId: string]: Group };
// public readonly instanceMapForTg = {} as { [tgUserId: string]: Group };
constructor(
public readonly qq: Friend | Group,
private _tg: TelegramChat,
// public readonly tgUser: TelegramChat,
public dbId: number,
private _flags: number,
) {

View File

@ -199,7 +199,7 @@ export default class ConfigService {
// 关联写入数据库
const chatForBot = await this.tgBot.getChat(chat.id);
status && await status.edit({ text: '正在写数据库…' });
const dbPair = await this.instance.forwardPairs.add(room, chatForBot);
const dbPair = await this.instance.forwardPairs.add(room, chatForBot, chat);
isFinish = true;
// 更新头像
@ -252,7 +252,8 @@ export default class ConfigService {
try {
const qGroup = this.oicq.getChat(qqRoomId) as Group;
const tgChat = await this.tgBot.getChat(tgChatId);
await this.instance.forwardPairs.add(qGroup, tgChat);
const tgUserChat = await this.tgUser.getChat(tgChatId);
await this.instance.forwardPairs.add(qGroup, tgChat, tgUserChat);
await tgChat.sendMessage(`QQ群${qGroup.name} (<code>${qGroup.group_id}</code>)已与 ` +
`Telegram 群 ${(tgChat.entity as Api.Channel).title} (<code>${tgChatId}</code>)关联`);
if (!(tgChat.entity instanceof Api.Channel)) {

View File

@ -377,7 +377,7 @@ export default class ForwardService {
else if (files.length) {
messageToSend.file = files;
}
else if ((pair.flags | this.instance.flags) & flags.RICH_HEADER) {
else if (event.message_type === 'group' && (pair.flags | this.instance.flags) & flags.RICH_HEADER) {
// 没有文件时才能显示链接预览
richHeaderUsed = true;
const url = new URL('https://q2tg-header.clansty.workers.dev');
@ -410,6 +410,7 @@ export default class ForwardService {
}
catch (e) {
if (richHeaderUsed) {
richHeaderUsed = false;
this.log.warn('Rich Header 发送错误', messageToSend.file, e);
delete messageToSend.file;
delete messageToSend.linkPreview;
@ -420,6 +421,23 @@ export default class ForwardService {
else throw e;
}
if (richHeaderUsed) {
// 测试 Web Preview 内容是否被正确获取
setTimeout(async () => {
// Telegram Bot 账号无法获取 Web 预览内容,只能用 User 账号获取
const userMessage = await pair.tgUser.getMessage({
ids: tgMessage.id,
});
if (['WebPage', 'WebPageNotModified'].includes((userMessage.media as Api.MessageMediaWebPage)?.webpage?.className))
return;
// 没有正常获取的话,就加上原先的头部
this.log.warn('Rich Header 回测错误', messageToSend.file);
await tgMessage.edit({
text: messageHeader + (message && messageHeader ? '\n' : '') + message,
});
}, 3000);
}
if (this.instance.workMode === 'personal' && event.message_type === 'group' && event.atall) {
await tgMessage.pin({ notify: false });
}