feat: 加入 Zinc Search 搜索

This commit is contained in:
Clansty 2023-03-01 22:16:54 +08:00
parent 9357207aff
commit dd6cffcf4d
No known key found for this signature in database
8 changed files with 169 additions and 2 deletions

View File

@ -43,7 +43,9 @@
"sharp": "^0.31.3",
"silk-sdk": "^0.2.2",
"telegram": "^2.15.2",
"tmp-promise": "^3.0.3"
"tmp-promise": "^3.0.3",
"undici": "^5.20.0",
"zincsearch-node": "^2.1.0"
},
"engines": {
"node": "^14.13.1 || >=16.0.0"

View File

@ -53,6 +53,10 @@ const inChatCommands = [
command: 'info',
description: '查看本群或选定消息的详情',
}),
new Api.BotCommand({
command: 'search',
description: '搜索消息',
}),
];
const groupInChatCommands = [

View File

@ -17,6 +17,7 @@ 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';
export default class ForwardController {
private readonly forwardService: ForwardService;
@ -71,6 +72,10 @@ export default class ForwardController {
tgSenderId: BigInt(this.tgBot.me.id.toString()),
},
});
await this.forwardService.addToZinc(pair.dbId, tgMessage.id, {
text: event.raw_message,
nick: event.nickname,
});
}
}
catch (e) {
@ -107,6 +112,10 @@ export default class ForwardController {
tgSenderId: BigInt((message.senderId || message.sender?.id).toString()),
},
});
await this.forwardService.addToZinc(pair.dbId, message.id, {
text: qqMessageSent.brief,
nick: helper.getUserDisplayName(message.sender),
});
}
}
}

View File

@ -90,6 +90,11 @@ export default class InChatCommandsController {
const helper = new RecoverMessageHelper(this.instance, this.tgBot, this.tgUser, this.oicq, pair, message);
helper.startRecover().then(() => this.log.info('恢复完成'));
return true;
case '/search':
await message.reply({
message: await this.service.search(messageParts, pair),
});
return true;
}
};
}

View File

@ -34,17 +34,26 @@ import _ from 'lodash';
import emoji from '../constants/emoji';
import convert from '../helpers/convert';
import { QQMessageSent } from '../types/definitions';
import ZincSearch from 'zincsearch-node';
const NOT_CHAINABLE_ELEMENTS = ['flash', 'record', 'video', 'location', 'share', 'json', 'xml', 'poke'];
// noinspection FallThroughInSwitchStatementJS
export default class ForwardService {
private readonly log: Logger;
private readonly zincSearch: ZincSearch;
constructor(private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly oicq: OicqClient) {
this.log = getLogger(`ForwardService - ${instance.id}`);
if (process.env.ZINC_URL) {
this.zincSearch = new ZincSearch({
url: process.env.ZINC_URL,
user: process.env.ZINC_USERNAME,
password: process.env.ZINC_PASSWORD,
});
}
}
public async forwardFromQq(event: PrivateMessageEvent | GroupMessageEvent, pair: Pair) {
@ -326,7 +335,7 @@ export default class ForwardService {
}
}
async forwardFromTelegram(message: Api.Message, pair: Pair): Promise<Array<QQMessageSent>> {
public async forwardFromTelegram(message: Api.Message, pair: Pair): Promise<Array<QQMessageSent>> {
try {
const tempFiles: FileResult[] = [];
const chain: Sendable = [];
@ -584,4 +593,49 @@ export default class ForwardService {
}
}
}
public async addToZinc(pairId: number, tgMsgId: number, data: {
text: string,
nick: string,
}) {
if (!this.zincSearch) return;
const existsReq = await fetch(process.env.ZINC_URL + `/api/index/q2tg-${pairId}`, {
method: 'HEAD',
headers: {
Authorization: 'Basic ' + Buffer.from(process.env.ZINC_USERNAME + ':' + process.env.ZINC_PASSWORD).toString('base64'),
},
});
if (existsReq.status === 404) {
await this.zincSearch.indices.create({
name: `q2tg-${pairId}`,
mappings: {
properties: {
nick: {
type: 'text',
index: true,
store: false,
aggregatable: false,
highlightable: true,
analyzer: 'gse_search',
search_analyzer: 'gse_standard',
},
text: {
type: 'text',
index: true,
store: false,
aggregatable: false,
highlightable: true,
analyzer: 'gse_search',
search_analyzer: 'gse_standard',
},
},
},
});
}
await this.zincSearch.document.createOrUpdate({
id: tgMsgId.toString(),
index: `q2tg-${pairId}`,
document: data,
});
}
}

View File

@ -10,14 +10,23 @@ import { getAvatar } from '../utils/urls';
import db from '../models/db';
import { Friend, Group } from 'oicq';
import { format } from 'date-and-time';
import ZincSearch from 'zincsearch-node';
export default class InChatCommandsService {
private readonly log: Logger;
private readonly zincSearch: ZincSearch;
constructor(private readonly instance: Instance,
private readonly tgBot: Telegram,
private readonly oicq: OicqClient) {
this.log = getLogger(`InChatCommandsService - ${instance.id}`);
if (process.env.ZINC_URL) {
this.zincSearch = new ZincSearch({
url: process.env.ZINC_URL,
user: process.env.ZINC_USERNAME,
password: process.env.ZINC_PASSWORD,
});
}
}
public async info(message: Api.Message, pair: Pair) {
@ -116,4 +125,24 @@ export default class InChatCommandsService {
});
}
}
public async search(keywords: string[], pair: Pair) {
const queries = keywords.map((txt) => `text:${txt}`);
const result = await this.zincSearch.search({
index: `q2tg-${pair.dbId}`,
query: { term: queries.join(' '), terms: [] },
search_type: 'match',
sort_fields: ['-_score'],
max_results: 5,
});
if (!result.hits?.hits?.length) {
return '没有结果';
}
const rpy = result.hits.hits.map((hit, index) => {
const id = hit._id!;
const link = `https://t.me/c/${pair.tgId}/${id}`;
return `${index + 1}. ${link} score:${hit._score!.toFixed(3)}`;
});
return rpy.join('\n');
}
}

View File

@ -161,15 +161,18 @@ cacheEntries = {
"@types/sharp@npm:0.31.1" = { filename = "@types-sharp-npm-0.31.1-2fd1486480-226871181f.zip"; sha512 = "226871181fc88b5ef8a6bc32c1e14a3426cc45480ed49536c45bb5c166c089169b8fe3e5c57aea8c34cc40b08311a95d5582c1a2f540f4425eb66fea3d6e0489"; };
"cli-progress@npm:3.11.2" = { filename = "cli-progress-npm-3.11.2-6cecb7043d-147d26b80c.zip"; sha512 = "147d26b80ceaa24d72f0354d1b58b7f3567b928bf5943be879de31cf16b0a4f1d059984e2e35a664d7d27ae3e7fafd69fd94b35f462c8879caf96d7f31eac442"; };
"tmp-promise@npm:3.0.3" = { filename = "tmp-promise-npm-3.0.3-6df4ad8df9-f854f5307d.zip"; sha512 = "f854f5307dcee6455927ec3da9398f139897faf715c5c6dcee6d9471ae85136983ea06662eba2edf2533bdcb0fca66d16648e79e14381e30c7fb20be9c1aa62c"; };
"zincsearch-node@npm:2.1.0" = { filename = "zincsearch-node-npm-2.1.0-939476f4a5-a1995fda22.zip"; sha512 = "a1995fda2226b785eacafde1dde4f3ef30f51a32190567e38120ac032645c316317dc4938f26505528375645261edd48c69cfce221d00ceacc20a0b5549ef9ef"; };
"axios@npm:0.27.2" = { filename = "axios-npm-0.27.2-dbe3a48aea-38cb754046.zip"; sha512 = "38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854"; };
"fluent-ffmpeg@npm:2.1.2" = { filename = "fluent-ffmpeg-npm-2.1.2-692c218f68-ab7ed90948.zip"; sha512 = "ab7ed909486298f33b991af051c38e40410ae5b03b0b6d33d0855636a0b56330ffe9efed6c7eedb00f1c6c713c795cbdb283f6f2216db925ae5e737a22c6a97f"; };
"prompts@npm:2.4.2" = { filename = "prompts-npm-2.4.2-f5d25d5eea-d8fd1fe638.zip"; sha512 = "d8fd1fe63820be2412c13bfc5d0a01909acc1f0367e32396962e737cb2fc52d004f3302475d5ce7d18a1e8a79985f93ff04ee03007d091029c3f9104bffc007d"; };
"file-type@npm:17.1.4" = { filename = "file-type-npm-17.1.4-72b08f1f60-07ae79cda0.zip"; sha512 = "07ae79cda01a38c2dedec85acfa7d5532c8334d4bc8542e0ab97e27d1bc496d325ea245bb546394f43ac19673fad6ef50fc38a9d70462ae2f5a28ab8721d1037"; };
"silk-sdk@npm:0.2.2" = { filename = "silk-sdk-npm-0.2.2-2c0636bebf-e6314428f1.zip"; sha512 = "e6314428f1e406e59ffb400bb0493dfa056d1ffcf36afa60de59cfe22937ce70f5b7a08757510880755dbf1cb9137a298947641b10e7d1369bdd421674afdbec"; };
"undici@npm:5.20.0" = { filename = "undici-npm-5.20.0-e0d42e5e9b-25412a785b.zip"; sha512 = "25412a785b2bd0b12f0bb0ec47ef00aa7a611ca0e570cb7af97cffe6a42e0d78e4b15190363a43771e9002defc3c6647c1b2d52201b3f64e2196819db4d150d3"; };
"@prisma/engines-version@npm:4.6.0-53.2e719efb80b56a3f32d18a62489de95bb9c130e3" = { filename = "@prisma-engines-version-npm-4.6.0-53.2e719efb80b56a3f32d18a62489de95bb9c130e3-7777b7153b-88510cec37.zip"; sha512 = "88510cec375f1505953121a41fa464f26be4022859cfe40659e4cb15c7e8d22d163203a30d65f2e66c828287cf029eb92ab6ba7325c6b3f551f92fb52424477b"; };
"@types/node@npm:17.0.21" = { filename = "@types-node-npm-17.0.21-7d68eb6a13-89dcd2fe82.zip"; sha512 = "89dcd2fe82f21d3634266f8384e9c865cf8af49685639fbdbd799bdd1040480fb1e8eeda2d3b9fce41edbe704d2a4be9f427118c4ae872e8d9bb7cbeb3c41a94"; };
"log4js@npm:6.6.1" = { filename = "log4js-npm-6.6.1-00e7698906-68f29e7b8b.zip"; sha512 = "68f29e7b8b0efa2f987e65ee122fde0bc806dd7ad20f0a9f2da316696423e42381ba348bd6e2f6a2feba042a6ed33c14955210741f47ab897b3204aba8bcd84b"; };
"oicq@https://0w.al/KyZD.tar.gz" = { filename = "oicq-https-79479db55d-5b735c0333.zip"; sha512 = "5b735c03331e1f0f2c85bd102902465e432a3ebe3cb165ce02591a738554cb45edcf398acc8c5b63da9fe13f9d364ae04f75fd8c849ed12e11ad99832d6061de"; };
"typescript@npm:4.9.5" = { filename = "typescript-npm-4.9.5-6427b65ee6-ee000bc268.zip"; sha512 = "ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db"; };
"follow-redirects@npm:1.15.1" = { filename = "follow-redirects-npm-1.15.1-6b191885cd-6aa4e3e3cd.zip"; sha512 = "6aa4e3e3cdfa3b9314801a1cd192ba756a53479d9d8cca65bf4db3a3e8834e62139245cd2f9566147c8dfe2efff1700d3e6aefd103de4004a7b99985e71dd533"; };
"async@npm:3.2.3" = { filename = "async-npm-3.2.3-e9d6b79c88-c4bee57ab2.zip"; sha512 = "c4bee57ab2249af3dc83ca3ef9acfa8e822c0d5e5aa41bae3eaf7f673648343cd64ecd7d26091ffd357f3f044428b17b5f00098494b6cf8b6b3e9681f0636ca1"; };
"kleur@npm:3.0.3" = { filename = "kleur-npm-3.0.3-f6f53649a4-df82cd1e17.zip"; sha512 = "df82cd1e172f957bae9c536286265a5cdbd5eeca487cb0a3b2a7b41ef959fc61f8e7c0e9aeea9c114ccf2c166b6a8dd45a46fd619c1c569d210ecd2765ad5169"; };
@ -214,6 +217,7 @@ cacheEntries = {
"semver@npm:7.3.8" = { filename = "semver-npm-7.3.8-25a996cb4f-ba9c7cbbf2.zip"; sha512 = "ba9c7cbbf2b7884696523450a61fee1a09930d888b7a8d7579025ad93d459b2d1949ee5bbfeb188b2be5f4ac163544c5e98491ad6152df34154feebc2cc337c1"; };
"tunnel-agent@npm:0.6.0" = { filename = "tunnel-agent-npm-0.6.0-64345ab7eb-05f6510358.zip"; sha512 = "05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711"; };
"readable-stream@npm:3.6.0" = { filename = "readable-stream-npm-3.6.0-23a4a5eb56-d4ea81502d.zip"; sha512 = "d4ea81502d3799439bb955a3a5d1d808592cf3133350ed352aeaa499647858b27b1c4013984900238b0873ec8d0d8defce72469fb7a83e61d53f5ad61cb80dc8"; };
"typescript@patch:typescript@npm%3A4.9.5#~builtin<compat/typescript>::version=4.9.5&hash=493e53" = { filename = "typescript-patch-d1f41f1b4a-2eee5c37ca.zip"; sha512 = "2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20"; };
"color@npm:4.2.3" = { filename = "color-npm-4.2.3-4a23227581-0579629c02.zip"; sha512 = "0579629c02c631b426780038da929cca8e8d80a40158b09811a0112a107c62e10e4aad719843b791b1e658ab4e800558f2e87ca4522c8b32349d497ecb6adeb4"; };
"follow-redirects@npm:1.15.2" = { filename = "follow-redirects-npm-1.15.2-1ec1dd82be-faa66059b6.zip"; sha512 = "faa66059b66358ba65c234c2f2a37fcec029dc22775f35d9ad6abac56003268baf41e55f9ee645957b32c7d9f62baf1f0b906e68267276f54ec4b4c597c2b190"; };
"proxy-from-env@npm:1.1.0" = { filename = "proxy-from-env-npm-1.1.0-c13d07f26b-ed7fcc2ba0.zip"; sha512 = "ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4"; };
@ -625,6 +629,8 @@ cacheEntries = {
"process@npm:0.11.10" = { filename = "process-npm-0.11.10-aeb3b641ae-bfcce49814.zip"; sha512 = "bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3"; };
"min-document@npm:2.19.0" = { filename = "min-document-npm-2.19.0-458cdb3d84-da6437562e.zip"; sha512 = "da6437562ea2228041542a2384528e74e22d1daa1a4ec439c165abf0b9d8a63e17e3b8a6dc6e0c731845e85301198730426932a0e813d23f932ca668340c9623"; };
"dom-walk@npm:0.1.2" = { filename = "dom-walk-npm-0.1.2-7d20a1a8d8-19eb0ce9c6.zip"; sha512 = "19eb0ce9c6de39d5e231530685248545d9cd2bd97b2cb3486e0bfc0f2a393a9addddfd5557463a932b52fdfcf68ad2a619020cd2c74a5fe46fbecaa8e80872f3"; };
"busboy@npm:1.6.0" = { filename = "busboy-npm-1.6.0-ebb5cbb04b-32801e2c01.zip"; sha512 = "32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e"; };
"streamsearch@npm:1.1.0" = { filename = "streamsearch-npm-1.1.0-fc3ad6536d-1cce16cea8.zip"; sha512 = "1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942"; };
};
in optionalOverride overrideAttrs project

View File

@ -971,6 +971,15 @@ __metadata:
languageName: node
linkType: hard
"busboy@npm:^1.6.0":
version: 1.6.0
resolution: "busboy@npm:1.6.0"
dependencies:
streamsearch: ^1.1.0
checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e
languageName: node
linkType: hard
"bytes@npm:3.1.2, bytes@npm:^3.1.0":
version: 3.1.2
resolution: "bytes@npm:3.1.2"
@ -3354,6 +3363,8 @@ __metadata:
ts-node: ^10.9.1
tsc: ^2.0.4
typescript: ^4.7.4
undici: ^5.20.0
zincsearch-node: ^2.1.0
bin:
q2tg: build/index.js
languageName: unknown
@ -3831,6 +3842,13 @@ __metadata:
languageName: node
linkType: hard
"streamsearch@npm:^1.1.0":
version: 1.1.0
resolution: "streamsearch@npm:1.1.0"
checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942
languageName: node
linkType: hard
"string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.2.3":
version: 4.2.3
resolution: "string-width@npm:4.2.3"
@ -4204,6 +4222,16 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:^4.9.3":
version: 4.9.5
resolution: "typescript@npm:4.9.5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db
languageName: node
linkType: hard
"typescript@patch:typescript@^4.7.4#~builtin<compat/typescript>":
version: 4.7.4
resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin<compat/typescript>::version=4.7.4&hash=493e53"
@ -4214,6 +4242,25 @@ __metadata:
languageName: node
linkType: hard
"typescript@patch:typescript@^4.9.3#~builtin<compat/typescript>":
version: 4.9.5
resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin<compat/typescript>::version=4.9.5&hash=493e53"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 2eee5c37cad4390385db5db5a8e81470e42e8f1401b0358d7390095d6f681b410f2c4a0c496c6ff9ebd775423c7785cdace7bcdad76c7bee283df3d9718c0f20
languageName: node
linkType: hard
"undici@npm:^5.20.0":
version: 5.20.0
resolution: "undici@npm:5.20.0"
dependencies:
busboy: ^1.6.0
checksum: 25412a785b2bd0b12f0bb0ec47ef00aa7a611ca0e570cb7af97cffe6a42e0d78e4b15190363a43771e9002defc3c6647c1b2d52201b3f64e2196819db4d150d3
languageName: node
linkType: hard
"unique-filename@npm:^1.1.1":
version: 1.1.1
resolution: "unique-filename@npm:1.1.1"
@ -4569,3 +4616,14 @@ __metadata:
checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6
languageName: node
linkType: hard
"zincsearch-node@npm:^2.1.0":
version: 2.1.0
resolution: "zincsearch-node@npm:2.1.0"
dependencies:
typescript: ^4.9.3
peerDependencies:
undici: ">=5.10.0"
checksum: a1995fda2226b785eacafde1dde4f3ef30f51a32190567e38120ac032645c316317dc4938f26505528375645261edd48c69cfce221d00ceacc20a0b5549ef9ef
languageName: node
linkType: hard