Compare commits
No commits in common. "main" and "v1.3.0" have entirely different histories.
13 changed files with 163 additions and 651 deletions
|
|
@ -1,3 +1,4 @@
|
|||
version: "3.9"
|
||||
services:
|
||||
bot:
|
||||
build:
|
||||
|
|
@ -12,6 +13,5 @@ services:
|
|||
- "--keywords-file"
|
||||
- "/app/keywords.yml"
|
||||
- "--watch-file"
|
||||
# - "--reactions-collector-load-history"
|
||||
ports:
|
||||
- 0.0.0.0:9669:9669
|
||||
- 127.0.0.1:9669:9669
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@ keywords:
|
|||
# will match plain regex
|
||||
- name: woof
|
||||
pattern: 'w[oa]+f'
|
||||
# you can also specify flags for your regex
|
||||
flags:
|
||||
global: true
|
||||
multi_line: false
|
||||
insensitive: true
|
||||
|
||||
# will match regex wraped with word borders
|
||||
# will match 'hi, woof :3', 'woof!', 'i heard a woof' but not 'i like subwoofers'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "mtproto_exporter",
|
||||
"type": "module",
|
||||
"version": "1.5.3",
|
||||
"version": "1.3.0",
|
||||
"packageManager": "pnpm@10.6.5",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mtcute/dispatcher": "^0.27.6",
|
||||
"@mtcute/node": "^0.27.6",
|
||||
"@mtcute/dispatcher": "^0.22.2",
|
||||
"@mtcute/node": "^0.22.3",
|
||||
"command-line-args": "^6.0.1",
|
||||
"dotenv-cli": "^8.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
|
|
|
|||
316
pnpm-lock.yaml
generated
316
pnpm-lock.yaml
generated
|
|
@ -9,11 +9,11 @@ importers:
|
|||
.:
|
||||
dependencies:
|
||||
'@mtcute/dispatcher':
|
||||
specifier: ^0.27.6
|
||||
version: 0.27.6
|
||||
specifier: ^0.22.2
|
||||
version: 0.22.2
|
||||
'@mtcute/node':
|
||||
specifier: ^0.27.6
|
||||
version: 0.27.6
|
||||
specifier: ^0.22.3
|
||||
version: 0.22.3
|
||||
command-line-args:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
|
|
@ -104,25 +104,21 @@ packages:
|
|||
resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@7.27.1':
|
||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||
'@babel/helper-string-parser@7.25.9':
|
||||
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-identifier@7.25.9':
|
||||
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-validator-identifier@7.27.1':
|
||||
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/parser@7.27.5':
|
||||
resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==}
|
||||
'@babel/parser@7.27.0':
|
||||
resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/types@7.27.6':
|
||||
resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==}
|
||||
'@babel/types@7.27.0':
|
||||
resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@clack/core@0.4.1':
|
||||
|
|
@ -310,12 +306,6 @@ packages:
|
|||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
|
||||
'@eslint-community/eslint-utils@4.7.0':
|
||||
resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
|
||||
'@eslint-community/regexpp@4.12.1':
|
||||
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
|
|
@ -329,12 +319,12 @@ packages:
|
|||
eslint:
|
||||
optional: true
|
||||
|
||||
'@eslint/config-array@0.20.1':
|
||||
resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==}
|
||||
'@eslint/config-array@0.20.0':
|
||||
resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/config-helpers@0.2.3':
|
||||
resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==}
|
||||
'@eslint/config-helpers@0.2.1':
|
||||
resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/core@0.10.0':
|
||||
|
|
@ -369,25 +359,17 @@ packages:
|
|||
resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@fuman/io@0.0.17':
|
||||
resolution: {integrity: sha512-VmMnfHtXzBfEddEfptn/oYshUzWqW2XUkdVnwKuHWphEQTQZrOWxC7G12FI9U2EhEYt4nRdrUTYk65U8GVJWYw==}
|
||||
'@fuman/io@0.0.8':
|
||||
resolution: {integrity: sha512-+cRZ2JOMYceNQ2Rh6UYro5XVa11j29Sdd3Yhi4GfxAx6ZwCNIw3P80xcTRwCZSfMPLDNN9Etkq7NIc5v9lpItw==}
|
||||
|
||||
'@fuman/net@0.0.17':
|
||||
resolution: {integrity: sha512-x/kK3kWQ+gy5rfsoS6QVCsodh9n/XJeM3c6m1YHPUiQ0gWWQd4CC1bcQ/rh2UHh9DQyJJeWjCQXWH2xmsVCcFQ==}
|
||||
'@fuman/net@0.0.9':
|
||||
resolution: {integrity: sha512-asn7VJbT8woVXAFCUMZrdyNZCSsXZclraeVZ6RYJ+T3RwQ+JfMMZtXLLTZ7XHrBPxk8x8hoHOJa/Fnyfm+ggbQ==}
|
||||
|
||||
'@fuman/node@0.0.17':
|
||||
resolution: {integrity: sha512-XXRlJthuCnJBnIrg/tZcqCfv/cPuXuNOVUN521oJgKrW8FyFmt+lAt2MlYw3TROumGNRMtvn3ySjdQRpBT2sLw==}
|
||||
peerDependencies:
|
||||
ws: ^8.18.1
|
||||
peerDependenciesMeta:
|
||||
ws:
|
||||
optional: true
|
||||
'@fuman/node@0.0.9':
|
||||
resolution: {integrity: sha512-ImOGEv1T1n/AOqfPH8ag1q/i0RvxnG0EfYVwlfRl/PXW/uNJiH3PRgT4euvXPNlHx6DViDiFn4ADecz9bTrtUg==}
|
||||
|
||||
'@fuman/utils@0.0.15':
|
||||
resolution: {integrity: sha512-3H3WzkfG7iLKCa/yNV4s80lYD4yr5hgiNzU13ysLY2BcDqFjM08XGYuLd5wFVp4V8+DA/fe8gIDW96To/JwDyA==}
|
||||
|
||||
'@fuman/utils@0.0.17':
|
||||
resolution: {integrity: sha512-hy1Xu1146nOspVam8FC6p4yakb1FV1V3KrS85RzcHiK7AccFKR43Fgtv8exC8Ybsw6MtMU+MRNyaPqVhA+7TsA==}
|
||||
'@fuman/utils@0.0.4':
|
||||
resolution: {integrity: sha512-YBZIlGDbM8s9G85pWFZJ9wQrDY4511XLHZ06/uxZfXBY0eSStwje8JFNmRMNF0SjRk4D3iRmPl9wirHKTkg89w==}
|
||||
|
||||
'@humanfs/core@0.19.1':
|
||||
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
|
||||
|
|
@ -405,39 +387,39 @@ packages:
|
|||
resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
|
||||
engines: {node: '>=18.18'}
|
||||
|
||||
'@humanwhocodes/retry@0.4.3':
|
||||
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
|
||||
'@humanwhocodes/retry@0.4.2':
|
||||
resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==}
|
||||
engines: {node: '>=18.18'}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.0':
|
||||
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
|
||||
|
||||
'@mtcute/core@0.27.6':
|
||||
resolution: {integrity: sha512-OqjQ2hchF15yJAjcAgBuWx4RCnvMED0P3kiUfU3EsDMMIJlh8TgOgm0QspIda/Uz7icZ5+pi0rHyCYblw2MMKw==}
|
||||
'@mtcute/core@0.22.3':
|
||||
resolution: {integrity: sha512-oyCSliNUBsLlHn4aNPfB/lWEleZFGk1dhcmC0LoVlqHvZN22/RiwRDxJPdlGqjfq6/dSmNbz+n7EZjna3CB1dA==}
|
||||
|
||||
'@mtcute/dispatcher@0.27.6':
|
||||
resolution: {integrity: sha512-5ZmI5cmyeWVYY5BtPlGYB0b4oxmF86xiP/c1Wo3VQ0SElYuknf+xZDlFxt6AMlHk9d/v2rxEd+dBXB5kRczpUA==}
|
||||
'@mtcute/dispatcher@0.22.2':
|
||||
resolution: {integrity: sha512-pkvm1eLBD5SILcZjFHhHTaWw6eX8arygsyJNFh1R6IQLAOZmgRucDaj0rQD+vNJzEJJNFsvZABc0yq+IVvi3jA==}
|
||||
|
||||
'@mtcute/file-id@0.27.6':
|
||||
resolution: {integrity: sha512-ZSPxbGjS6YdcZv4xW0zHJ/iR28nEBisG3G6gDTwVS4gU51SJ4vlGcwGjF1uLyEeuGGbPFemQHLCP6CMSzqMRvA==}
|
||||
'@mtcute/file-id@0.22.0':
|
||||
resolution: {integrity: sha512-siY+eGrfYvTuC2xuyf4oaD09ZpaLtG2qrOlwdEpwXFnyjjavsQyWkyPwAemTPclcRuYB+/axD9+RBhj3EGBNSQ==}
|
||||
|
||||
'@mtcute/html-parser@0.27.6':
|
||||
resolution: {integrity: sha512-zxTuT0nv0CBR4qy7KyKB9vGQ++DxeiofKJEwHFSj5oG/7qUARm21G5GZaVlel/v7oRzx6V3u9mKDzdlbv8BcxA==}
|
||||
'@mtcute/html-parser@0.22.1':
|
||||
resolution: {integrity: sha512-KojNrJPvbsRyzc0pBbRrU03VZfgRRj+gkWBP+lcXJgdM+SypGkxUM2wQMxCwsRQ8JVGAmGLna1IPrYoiBW0rJw==}
|
||||
|
||||
'@mtcute/markdown-parser@0.27.6':
|
||||
resolution: {integrity: sha512-YB4HXeDGQi+ilbOp1qDJ/iP3VfBFrsR+gEyQcaQo/PAR4NLtD+rZ5veWM/OSVjbawYl2OpFpfXzQdINAAlaEJg==}
|
||||
'@mtcute/markdown-parser@0.22.3':
|
||||
resolution: {integrity: sha512-kg7oOEX69Y5LJd2E52uLZWilSetbEHWSO8R1XVrI0ONaL3T2NnGDaGZGI80KuI4CCpNyWdDqB6EggoBeQJshnA==}
|
||||
|
||||
'@mtcute/node@0.27.6':
|
||||
resolution: {integrity: sha512-fDnufwcRJyqMr7rpCIiSW6GIRR1j+tgM8Og1Rx38U16Ftmu3gB7Xt5K7lHJJWQHDhv59w8AiU+NksiPdTXbxxQ==}
|
||||
'@mtcute/node@0.22.3':
|
||||
resolution: {integrity: sha512-KTJ7O/mzXpBMcF0K/NPksfpQovIhOXayTdiP/cHrSp7VMdBBeo+5G1THk1SwPWi6iFmz3AS5d+WO+Ybff08qFg==}
|
||||
|
||||
'@mtcute/tl-runtime@0.24.3':
|
||||
resolution: {integrity: sha512-61J3cgYgNOQT532GdIiuezRrSC7v6cc9MfvWv9GO27bRGf7JUKWVbFt4U0KzQ9Tp0J1uMOUfi1EbQKkYKacIKQ==}
|
||||
'@mtcute/tl-runtime@0.22.0':
|
||||
resolution: {integrity: sha512-t4ThFk7gCrgMa5sx+C+2qDwKmNuWLKMK/75oGYhsa7IJLgdGc+s4F+SM5TA0DynmG/sUh2BfYNZr6/rotJM01A==}
|
||||
|
||||
'@mtcute/tl@221.0.0':
|
||||
resolution: {integrity: sha512-Wp01L9nznTMLl2s9rbKnzQ8pij72eF4HK2XIziOQoJXiObPKZxQdxvMj+C6l0ArxMFmpT0H0/3EL5RB7O6VPwg==}
|
||||
'@mtcute/tl@200.0.0':
|
||||
resolution: {integrity: sha512-YMiWjLMtqRSoUxcJbrCt2a8VWbIYDkvmipOmvNR2oAFzFmYmYXjR+jYDnbt1zmBoRWc3IrwddqdkVGK99Sc4bQ==}
|
||||
|
||||
'@mtcute/wasm@0.27.0':
|
||||
resolution: {integrity: sha512-1v4eO1N1BVRQ8L+cyUsMAeLXs5suTGXyVv/tftkbd/mGGHxc+fvOWItp3Fmq+GIwN7m4VX7kztuMMLhHxv2i2Q==}
|
||||
'@mtcute/wasm@0.22.3':
|
||||
resolution: {integrity: sha512-YyzxgWcx30HYuBsxvu43IDekIXV2u5xhdEPXqf7SCYDvWDZtQJ2ox3s4BPspRJ0LiKuYtaY4pdny+7I741Hcog==}
|
||||
|
||||
'@napi-rs/wasm-runtime@0.2.8':
|
||||
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
|
||||
|
|
@ -490,9 +472,6 @@ packages:
|
|||
'@types/estree@1.0.7':
|
||||
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
|
||||
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
'@types/events@3.0.0':
|
||||
resolution: {integrity: sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==}
|
||||
|
||||
|
|
@ -677,11 +656,6 @@ packages:
|
|||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
acorn@8.15.0:
|
||||
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
|
|
@ -710,9 +684,8 @@ packages:
|
|||
base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
better-sqlite3@12.6.2:
|
||||
resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==}
|
||||
engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x}
|
||||
better-sqlite3@11.3.0:
|
||||
resolution: {integrity: sha512-iHt9j8NPYF3oKCNOO5ZI4JwThjt3Z6J6XrcwG85VNMVzv1ByqrHWv5VILEbCMFWDsoHhXvQ7oC8vgRXFAKgl9w==}
|
||||
|
||||
bindings@1.5.0:
|
||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||
|
|
@ -726,8 +699,8 @@ packages:
|
|||
boolbase@1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==}
|
||||
brace-expansion@1.1.11:
|
||||
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
|
||||
|
||||
brace-expansion@2.0.1:
|
||||
resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
|
||||
|
|
@ -838,15 +811,6 @@ packages:
|
|||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.1:
|
||||
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decode-named-character-reference@1.1.0:
|
||||
resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==}
|
||||
|
||||
|
|
@ -1087,10 +1051,6 @@ packages:
|
|||
resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
eslint-scope@8.4.0:
|
||||
resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
eslint-visitor-keys@3.4.3:
|
||||
resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
|
@ -1099,10 +1059,6 @@ packages:
|
|||
resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
eslint-visitor-keys@4.2.1:
|
||||
resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
eslint@9.24.0:
|
||||
resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
|
@ -1117,10 +1073,6 @@ packages:
|
|||
resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
espree@10.4.0:
|
||||
resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
espree@9.6.1:
|
||||
resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
|
@ -1654,8 +1606,8 @@ packages:
|
|||
resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postcss@8.5.6:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
postcss@8.5.3:
|
||||
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
|
|
@ -2021,20 +1973,18 @@ snapshots:
|
|||
js-tokens: 4.0.0
|
||||
picocolors: 1.1.1
|
||||
|
||||
'@babel/helper-string-parser@7.27.1': {}
|
||||
'@babel/helper-string-parser@7.25.9': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.25.9': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.27.1': {}
|
||||
|
||||
'@babel/parser@7.27.5':
|
||||
'@babel/parser@7.27.0':
|
||||
dependencies:
|
||||
'@babel/types': 7.27.6
|
||||
'@babel/types': 7.27.0
|
||||
|
||||
'@babel/types@7.27.6':
|
||||
'@babel/types@7.27.0':
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.27.1
|
||||
'@babel/helper-validator-identifier': 7.27.1
|
||||
'@babel/helper-string-parser': 7.25.9
|
||||
'@babel/helper-validator-identifier': 7.25.9
|
||||
|
||||
'@clack/core@0.4.1':
|
||||
dependencies:
|
||||
|
|
@ -2164,26 +2114,21 @@ snapshots:
|
|||
eslint: 9.24.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.7.0(eslint@9.24.0)':
|
||||
dependencies:
|
||||
eslint: 9.24.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/regexpp@4.12.1': {}
|
||||
|
||||
'@eslint/compat@1.2.8(eslint@9.24.0)':
|
||||
optionalDependencies:
|
||||
eslint: 9.24.0
|
||||
|
||||
'@eslint/config-array@0.20.1':
|
||||
'@eslint/config-array@0.20.0':
|
||||
dependencies:
|
||||
'@eslint/object-schema': 2.1.6
|
||||
debug: 4.4.1
|
||||
debug: 4.4.0
|
||||
minimatch: 3.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/config-helpers@0.2.3': {}
|
||||
'@eslint/config-helpers@0.2.1': {}
|
||||
|
||||
'@eslint/core@0.10.0':
|
||||
dependencies:
|
||||
|
|
@ -2200,8 +2145,8 @@ snapshots:
|
|||
'@eslint/eslintrc@3.3.1':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.4.1
|
||||
espree: 10.4.0
|
||||
debug: 4.4.0
|
||||
espree: 10.3.0
|
||||
globals: 14.0.0
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.1
|
||||
|
|
@ -2230,24 +2175,22 @@ snapshots:
|
|||
'@eslint/core': 0.13.0
|
||||
levn: 0.4.1
|
||||
|
||||
'@fuman/io@0.0.17':
|
||||
'@fuman/io@0.0.8':
|
||||
dependencies:
|
||||
'@fuman/utils': 0.0.17
|
||||
'@fuman/utils': 0.0.4
|
||||
|
||||
'@fuman/net@0.0.17':
|
||||
'@fuman/net@0.0.9':
|
||||
dependencies:
|
||||
'@fuman/io': 0.0.17
|
||||
'@fuman/utils': 0.0.17
|
||||
'@fuman/io': 0.0.8
|
||||
'@fuman/utils': 0.0.4
|
||||
|
||||
'@fuman/node@0.0.17':
|
||||
'@fuman/node@0.0.9':
|
||||
dependencies:
|
||||
'@fuman/io': 0.0.17
|
||||
'@fuman/net': 0.0.17
|
||||
'@fuman/utils': 0.0.17
|
||||
'@fuman/io': 0.0.8
|
||||
'@fuman/net': 0.0.9
|
||||
'@fuman/utils': 0.0.4
|
||||
|
||||
'@fuman/utils@0.0.15': {}
|
||||
|
||||
'@fuman/utils@0.0.17': {}
|
||||
'@fuman/utils@0.0.4': {}
|
||||
|
||||
'@humanfs/core@0.19.1': {}
|
||||
|
||||
|
|
@ -2260,66 +2203,64 @@ snapshots:
|
|||
|
||||
'@humanwhocodes/retry@0.3.1': {}
|
||||
|
||||
'@humanwhocodes/retry@0.4.3': {}
|
||||
'@humanwhocodes/retry@0.4.2': {}
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.0': {}
|
||||
|
||||
'@mtcute/core@0.27.6':
|
||||
'@mtcute/core@0.22.3':
|
||||
dependencies:
|
||||
'@fuman/io': 0.0.17
|
||||
'@fuman/net': 0.0.17
|
||||
'@fuman/utils': 0.0.17
|
||||
'@mtcute/file-id': 0.27.6
|
||||
'@mtcute/tl': 221.0.0
|
||||
'@mtcute/tl-runtime': 0.24.3
|
||||
'@fuman/io': 0.0.8
|
||||
'@fuman/net': 0.0.9
|
||||
'@fuman/utils': 0.0.4
|
||||
'@mtcute/file-id': 0.22.0
|
||||
'@mtcute/tl': 200.0.0
|
||||
'@mtcute/tl-runtime': 0.22.0
|
||||
'@types/events': 3.0.0
|
||||
long: 5.2.3
|
||||
|
||||
'@mtcute/dispatcher@0.27.6':
|
||||
'@mtcute/dispatcher@0.22.2':
|
||||
dependencies:
|
||||
'@fuman/utils': 0.0.17
|
||||
'@mtcute/core': 0.27.6
|
||||
'@fuman/utils': 0.0.4
|
||||
'@mtcute/core': 0.22.3
|
||||
|
||||
'@mtcute/file-id@0.27.6':
|
||||
'@mtcute/file-id@0.22.0':
|
||||
dependencies:
|
||||
'@fuman/utils': 0.0.17
|
||||
'@mtcute/tl-runtime': 0.24.3
|
||||
'@fuman/utils': 0.0.4
|
||||
'@mtcute/tl-runtime': 0.22.0
|
||||
long: 5.2.3
|
||||
|
||||
'@mtcute/html-parser@0.27.6':
|
||||
'@mtcute/html-parser@0.22.1':
|
||||
dependencies:
|
||||
'@mtcute/core': 0.27.6
|
||||
'@mtcute/core': 0.22.3
|
||||
htmlparser2: 10.0.0
|
||||
long: 5.2.3
|
||||
|
||||
'@mtcute/markdown-parser@0.27.6':
|
||||
'@mtcute/markdown-parser@0.22.3':
|
||||
dependencies:
|
||||
'@mtcute/core': 0.27.6
|
||||
'@mtcute/core': 0.22.3
|
||||
long: 5.2.3
|
||||
|
||||
'@mtcute/node@0.27.6':
|
||||
'@mtcute/node@0.22.3':
|
||||
dependencies:
|
||||
'@fuman/net': 0.0.17
|
||||
'@fuman/node': 0.0.17
|
||||
'@fuman/utils': 0.0.17
|
||||
'@mtcute/core': 0.27.6
|
||||
'@mtcute/html-parser': 0.27.6
|
||||
'@mtcute/markdown-parser': 0.27.6
|
||||
'@mtcute/wasm': 0.27.0
|
||||
better-sqlite3: 12.6.2
|
||||
transitivePeerDependencies:
|
||||
- ws
|
||||
'@fuman/net': 0.0.9
|
||||
'@fuman/node': 0.0.9
|
||||
'@fuman/utils': 0.0.4
|
||||
'@mtcute/core': 0.22.3
|
||||
'@mtcute/html-parser': 0.22.1
|
||||
'@mtcute/markdown-parser': 0.22.3
|
||||
'@mtcute/wasm': 0.22.3
|
||||
better-sqlite3: 11.3.0
|
||||
|
||||
'@mtcute/tl-runtime@0.24.3':
|
||||
'@mtcute/tl-runtime@0.22.0':
|
||||
dependencies:
|
||||
'@fuman/utils': 0.0.15
|
||||
'@fuman/utils': 0.0.4
|
||||
long: 5.2.3
|
||||
|
||||
'@mtcute/tl@221.0.0':
|
||||
'@mtcute/tl@200.0.0':
|
||||
dependencies:
|
||||
long: 5.2.3
|
||||
|
||||
'@mtcute/wasm@0.27.0': {}
|
||||
'@mtcute/wasm@0.22.3': {}
|
||||
|
||||
'@napi-rs/wasm-runtime@0.2.8':
|
||||
dependencies:
|
||||
|
|
@ -2378,8 +2319,6 @@ snapshots:
|
|||
|
||||
'@types/estree@1.0.7': {}
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@types/events@3.0.0': {}
|
||||
|
||||
'@types/js-yaml@4.0.9': {}
|
||||
|
|
@ -2533,7 +2472,7 @@ snapshots:
|
|||
|
||||
'@vue/compiler-core@3.5.13':
|
||||
dependencies:
|
||||
'@babel/parser': 7.27.5
|
||||
'@babel/parser': 7.27.0
|
||||
'@vue/shared': 3.5.13
|
||||
entities: 4.5.0
|
||||
estree-walker: 2.0.2
|
||||
|
|
@ -2546,14 +2485,14 @@ snapshots:
|
|||
|
||||
'@vue/compiler-sfc@3.5.13':
|
||||
dependencies:
|
||||
'@babel/parser': 7.27.5
|
||||
'@babel/parser': 7.27.0
|
||||
'@vue/compiler-core': 3.5.13
|
||||
'@vue/compiler-dom': 3.5.13
|
||||
'@vue/compiler-ssr': 3.5.13
|
||||
'@vue/shared': 3.5.13
|
||||
estree-walker: 2.0.2
|
||||
magic-string: 0.30.17
|
||||
postcss: 8.5.6
|
||||
postcss: 8.5.3
|
||||
source-map-js: 1.2.1
|
||||
|
||||
'@vue/compiler-ssr@3.5.13':
|
||||
|
|
@ -2567,14 +2506,8 @@ snapshots:
|
|||
dependencies:
|
||||
acorn: 8.14.1
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.15.0):
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
|
||||
acorn@8.14.1: {}
|
||||
|
||||
acorn@8.15.0: {}
|
||||
|
||||
ajv@6.12.6:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
|
|
@ -2598,7 +2531,7 @@ snapshots:
|
|||
|
||||
base64-js@1.5.1: {}
|
||||
|
||||
better-sqlite3@12.6.2:
|
||||
better-sqlite3@11.3.0:
|
||||
dependencies:
|
||||
bindings: 1.5.0
|
||||
prebuild-install: 7.1.3
|
||||
|
|
@ -2617,7 +2550,7 @@ snapshots:
|
|||
|
||||
boolbase@1.0.0: {}
|
||||
|
||||
brace-expansion@1.1.12:
|
||||
brace-expansion@1.1.11:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
concat-map: 0.0.1
|
||||
|
|
@ -2708,10 +2641,6 @@ snapshots:
|
|||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.1:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decode-named-character-reference@1.1.0:
|
||||
dependencies:
|
||||
character-entities: 2.0.2
|
||||
|
|
@ -3035,40 +2964,33 @@ snapshots:
|
|||
esrecurse: 4.3.0
|
||||
estraverse: 5.3.0
|
||||
|
||||
eslint-scope@8.4.0:
|
||||
dependencies:
|
||||
esrecurse: 4.3.0
|
||||
estraverse: 5.3.0
|
||||
|
||||
eslint-visitor-keys@3.4.3: {}
|
||||
|
||||
eslint-visitor-keys@4.2.0: {}
|
||||
|
||||
eslint-visitor-keys@4.2.1: {}
|
||||
|
||||
eslint@9.24.0:
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.7.0(eslint@9.24.0)
|
||||
'@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0)
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint/config-array': 0.20.1
|
||||
'@eslint/config-helpers': 0.2.3
|
||||
'@eslint/config-array': 0.20.0
|
||||
'@eslint/config-helpers': 0.2.1
|
||||
'@eslint/core': 0.12.0
|
||||
'@eslint/eslintrc': 3.3.1
|
||||
'@eslint/js': 9.24.0
|
||||
'@eslint/plugin-kit': 0.2.8
|
||||
'@humanfs/node': 0.16.6
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@humanwhocodes/retry': 0.4.3
|
||||
'@types/estree': 1.0.8
|
||||
'@humanwhocodes/retry': 0.4.2
|
||||
'@types/estree': 1.0.7
|
||||
'@types/json-schema': 7.0.15
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.6
|
||||
debug: 4.4.1
|
||||
debug: 4.4.0
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 8.4.0
|
||||
eslint-visitor-keys: 4.2.1
|
||||
espree: 10.4.0
|
||||
eslint-scope: 8.3.0
|
||||
eslint-visitor-keys: 4.2.0
|
||||
espree: 10.3.0
|
||||
esquery: 1.6.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
|
|
@ -3092,12 +3014,6 @@ snapshots:
|
|||
acorn-jsx: 5.3.2(acorn@8.14.1)
|
||||
eslint-visitor-keys: 4.2.0
|
||||
|
||||
espree@10.4.0:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
acorn-jsx: 5.3.2(acorn@8.15.0)
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
espree@9.6.1:
|
||||
dependencies:
|
||||
acorn: 8.14.1
|
||||
|
|
@ -3627,7 +3543,7 @@ snapshots:
|
|||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.12
|
||||
brace-expansion: 1.1.11
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
|
|
@ -3749,7 +3665,7 @@ snapshots:
|
|||
cssesc: 3.0.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
postcss@8.5.6:
|
||||
postcss@8.5.3:
|
||||
dependencies:
|
||||
nanoid: 3.3.11
|
||||
picocolors: 1.1.1
|
||||
|
|
|
|||
|
|
@ -10,45 +10,21 @@ export interface Configuration {
|
|||
wordsCounter: boolean;
|
||||
keywordsFile: string;
|
||||
watchFile: boolean;
|
||||
watchFileIntervalSeconds: number;
|
||||
includePeers?: number[];
|
||||
excludePeers?: number[];
|
||||
keywords?: RawKeywordLike[];
|
||||
collectors: {
|
||||
dialogs: boolean;
|
||||
messages: boolean;
|
||||
reactions: boolean;
|
||||
};
|
||||
reactionsCollector: {
|
||||
loadHistory: boolean;
|
||||
loadHistorySize: number;
|
||||
};
|
||||
messagesCollector: {
|
||||
includeSender: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/* eslint-disable style/no-multi-spaces, style/key-spacing */
|
||||
|
||||
const optionDefinitions: OptionDefinition[] = [
|
||||
{ name: "bind-host", alias: "b", type: String, defaultValue: "0.0.0.0" },
|
||||
{ name: "port", alias: "p", type: Number, defaultValue: 9669 },
|
||||
{ name: "words-counter", type: Boolean, defaultValue: false },
|
||||
{ name: "keywords-file", alias: "k", type: String },
|
||||
{ name: "watch-file", alias: "w", type: Boolean, defaultValue: false },
|
||||
{ name: "watch-file-interval-seconds", alias: "W", type: Number, defaultValue: 60 },
|
||||
{ name: "include-peers", alias: "i", type: String, multiple: true },
|
||||
{ name: "exclude-peers", alias: "x", type: String, multiple: true },
|
||||
{ name: "reactions-collector", type: Boolean, defaultValue: false },
|
||||
{ name: "reactions-collector-load-history", type: Boolean, defaultValue: false },
|
||||
{ name: "reactions-collector-load-history-size", type: Number, defaultValue: 1000 },
|
||||
{ name: "dialogs-collector", type: Boolean, defaultValue: true },
|
||||
{ name: "messages-collector", type: Boolean, defaultValue: true },
|
||||
{ name: "messages-collector-include-sender", type: Boolean, defaultValue: false },
|
||||
{ name: "bind-host", alias: "b", type: String, defaultValue: "0.0.0.0" },
|
||||
{ name: "port", alias: "p", type: Number, defaultValue: 9669 },
|
||||
{ name: "words-counter", type: Boolean, defaultValue: false },
|
||||
{ name: "keywords-file", alias: "k", type: String },
|
||||
{ name: "watch-file", alias: "w", type: Boolean, defaultValue: false },
|
||||
{ name: "include-peers", alias: "i", type: String, multiple: true },
|
||||
{ name: "exclude-peers", alias: "x", type: String, multiple: true },
|
||||
];
|
||||
|
||||
/* eslint-enable style/no-multi-spaces, style/key-spacing */
|
||||
|
||||
const cli = cmdline(optionDefinitions);
|
||||
|
||||
const config: Configuration = {
|
||||
|
|
@ -57,20 +33,7 @@ const config: Configuration = {
|
|||
wordsCounter: cli["words-counter"],
|
||||
keywordsFile: cli["keywords-file"],
|
||||
watchFile: cli["watch-file"],
|
||||
watchFileIntervalSeconds: cli["watch-file-interval-seconds"],
|
||||
keywords: cli["keywords-file"] ? await readKeywords(cli["keywords-file"]) : undefined,
|
||||
collectors: {
|
||||
dialogs: cli["dialogs-collector"],
|
||||
messages: cli["messages-collector"],
|
||||
reactions: cli["reactions-collector"],
|
||||
},
|
||||
reactionsCollector: {
|
||||
loadHistory: cli["reactions-collector-load-history"],
|
||||
loadHistorySize: cli["reactions-collector-load-history-size"],
|
||||
},
|
||||
messagesCollector: {
|
||||
includeSender: cli["messages-collector-include-sender"],
|
||||
},
|
||||
};
|
||||
|
||||
if (cli["include-peers"] && cli["exclude-peers"]) {
|
||||
|
|
@ -101,32 +64,11 @@ export async function readKeywords(filePath: string): Promise<RawKeywordLike[]>
|
|||
keywords.push(item);
|
||||
} else if (typeof item === "object" && typeof item.name === "string") {
|
||||
if (typeof item.pattern === "string") {
|
||||
const result = {
|
||||
keywords.push({
|
||||
name: item.name,
|
||||
pattern: item.pattern,
|
||||
word: Boolean(item.word ?? false),
|
||||
flags: {
|
||||
global: true,
|
||||
multi_line: false,
|
||||
insensitive: true,
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof item.flags === "object") {
|
||||
if (typeof item.flags.global === "boolean") {
|
||||
result.flags.global = item.flags.global;
|
||||
}
|
||||
|
||||
if (typeof item.flags.multi_line === "boolean") {
|
||||
result.flags.multi_line = item.flags.multi_line;
|
||||
}
|
||||
|
||||
if (typeof item.flags.insensitive === "boolean") {
|
||||
result.flags.insensitive = item.flags.insensitive;
|
||||
}
|
||||
}
|
||||
|
||||
keywords.push(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ const USERBOT_PHONE = process.env.USERBOT_PHONE;
|
|||
const USERBOT_2FACODE = process.env.USERBOT_2FACODE;
|
||||
const USERBOT_PASSWORD = process.env.USERBOT_PASSWORD;
|
||||
|
||||
const SOCKS_PROXY = process.env.SOCKS_PROXY;
|
||||
|
||||
if (Number.isNaN(API_ID) || !API_HASH) {
|
||||
throw new Error("API_ID or API_HASH not set!");
|
||||
}
|
||||
|
||||
export { API_HASH, API_ID, USERBOT_2FACODE, USERBOT_PASSWORD, USERBOT_PHONE, SOCKS_PROXY };
|
||||
export { API_HASH, API_ID, USERBOT_2FACODE, USERBOT_PASSWORD, USERBOT_PHONE };
|
||||
|
|
|
|||
65
src/main.ts
65
src/main.ts
|
|
@ -1,8 +1,8 @@
|
|||
import fs from "node:fs";
|
||||
import { Dispatcher } from "@mtcute/dispatcher";
|
||||
import { SocksProxyTcpTransport, TcpTransport, TelegramClient } from "@mtcute/node";
|
||||
|
||||
import { TelegramClient } from "@mtcute/node";
|
||||
import { collectDefaultMetrics, Registry } from "prom-client";
|
||||
|
||||
import { config, readKeywords } from "./config.js";
|
||||
import * as env from "./env.js";
|
||||
import { rawToPatterns } from "./metrics/keywords.js";
|
||||
|
|
@ -16,32 +16,10 @@ collectDefaultMetrics({ register: registry });
|
|||
const server = new MetricsServer(registry);
|
||||
server.listen(config.bindHost, config.port);
|
||||
|
||||
let transport;
|
||||
|
||||
if (env.SOCKS_PROXY) {
|
||||
const parts = env.SOCKS_PROXY!.split(":");
|
||||
if (parts.length !== 2) {
|
||||
throw new Error("Malformed SOCKS_PROXY: " + env.SOCKS_PROXY);
|
||||
}
|
||||
|
||||
const port = parseInt(parts[1]);
|
||||
if (isNaN(port) || port < 1 || port > 65535) {
|
||||
throw new Error("Invalid port in SOCKS_PROXY: " + parts[1]);
|
||||
}
|
||||
|
||||
transport = new SocksProxyTcpTransport({
|
||||
host: parts[0],
|
||||
port,
|
||||
});
|
||||
} else {
|
||||
transport = new TcpTransport();
|
||||
}
|
||||
|
||||
const tg = new TelegramClient({
|
||||
apiId: env.API_ID,
|
||||
apiHash: env.API_HASH,
|
||||
storage: "bot-data/session",
|
||||
transport,
|
||||
});
|
||||
|
||||
const dp = Dispatcher.for(tg);
|
||||
|
|
@ -54,49 +32,26 @@ const user = await tg.start({
|
|||
|
||||
console.log("Logged in as", user.username);
|
||||
|
||||
if (config.collectors.dialogs) {
|
||||
metrics.collectDialogMetrics(tg, registry);
|
||||
}
|
||||
|
||||
if (config.collectors.messages) {
|
||||
metrics.collectNewMessageMetrics(dp, registry);
|
||||
}
|
||||
|
||||
if (config.collectors.reactions) {
|
||||
console.log("[WARN] reactions-collector is enabled, but it is very experimental and almost does not work. i don't recommend enabling it especially for production use.");
|
||||
metrics.collectReactionsMetrics(tg, dp, registry);
|
||||
}
|
||||
metrics.collectDialogMetrics(tg, registry);
|
||||
metrics.collectNewMessageMetrics(dp, registry);
|
||||
|
||||
if (config.keywords) {
|
||||
const counter = new metrics.KeywordsCounter(dp, rawToPatterns(config.keywords));
|
||||
console.log("[keywords] Initialized keywords counter with", counter.keywords.length, "keywords/patterns.");
|
||||
|
||||
registry.registerMetric(counter);
|
||||
|
||||
if (config.watchFile) {
|
||||
const reloadConfig = async () => {
|
||||
fs.watchFile(config.keywordsFile, async (curr, prev) => {
|
||||
if (curr.mtimeMs === prev.mtimeMs) {
|
||||
return;
|
||||
}
|
||||
console.log("[watch-file] Keywords file was updated. Re-reading keywords configuration...");
|
||||
try {
|
||||
config.keywords = await readKeywords(config.keywordsFile);
|
||||
counter.setKeywords(rawToPatterns(config.keywords));
|
||||
console.log(`Loaded ${counter.keywords.length} keywords/patterns.`);
|
||||
} catch (e) {
|
||||
console.error("Failed to read keywords file", config.keywordsFile, e);
|
||||
}
|
||||
};
|
||||
|
||||
let lastMtimeMs = (await fs.promises.stat(config.keywordsFile)).mtimeMs;
|
||||
|
||||
setInterval(async () => {
|
||||
const stat = await fs.promises.stat(config.keywordsFile);
|
||||
if (lastMtimeMs === stat.mtimeMs) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastMtimeMs = stat.mtimeMs;
|
||||
|
||||
console.log("[watch-file] Keywords file was updated. Reloading keywords configuration...");
|
||||
await reloadConfig();
|
||||
}, config.watchFileIntervalSeconds * 1000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import type { Dialog, TelegramClient } from "@mtcute/node";
|
|||
import type { Registry } from "prom-client";
|
||||
import process from "node:process";
|
||||
import timers from "node:timers/promises";
|
||||
import { Gauge, Histogram, Summary } from "prom-client";
|
||||
|
||||
import { Gauge, Histogram } from "prom-client";
|
||||
import { config } from "../config.js";
|
||||
import { peersConfigBoolFilter } from "../filters.js";
|
||||
|
||||
|
|
@ -41,26 +41,9 @@ export function collectDialogMetrics(tg: TelegramClient, registry: Registry) {
|
|||
},
|
||||
});
|
||||
|
||||
const members = new Gauge({
|
||||
name: "messenger_dialog_chat_members_count",
|
||||
help: "Number of members in the chat",
|
||||
labelNames: ["peerId"],
|
||||
collect: async () => {
|
||||
members.reset();
|
||||
for (const d of await dialogs.get()) {
|
||||
if (d.peer.type !== "chat") continue;
|
||||
if (d.peer.membersCount === null) continue;
|
||||
members.set({
|
||||
peerId: d.peer.id,
|
||||
}, d.peer.membersCount);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
dialogs.registerMetrics(registry);
|
||||
registry.registerMetric(info);
|
||||
registry.registerMetric(unread);
|
||||
registry.registerMetric(members);
|
||||
}
|
||||
|
||||
class DialogsHolder {
|
||||
|
|
@ -70,7 +53,6 @@ class DialogsHolder {
|
|||
private ttl: bigint;
|
||||
|
||||
private dialogsIterDurationHistogram: Histogram;
|
||||
private dialogsIterDurationSummary: Summary;
|
||||
|
||||
constructor(private tg: TelegramClient, ttl: number, private timeout: number, private pollInterval = 10) {
|
||||
this.ttl = BigInt(ttl) * 1000000n;
|
||||
|
|
@ -78,15 +60,10 @@ class DialogsHolder {
|
|||
name: "telegram_api_dialogs_iter_duration",
|
||||
help: "Duration of iteration over telegram dialogs",
|
||||
});
|
||||
this.dialogsIterDurationSummary = new Summary({
|
||||
name: "telegram_api_dialogs_iter_duration_summary",
|
||||
help: "Duration of iteration over telegram dialogs",
|
||||
});
|
||||
}
|
||||
|
||||
public registerMetrics(registry: Registry) {
|
||||
registry.registerMetric(this.dialogsIterDurationHistogram);
|
||||
registry.registerMetric(this.dialogsIterDurationSummary);
|
||||
}
|
||||
|
||||
public async get() {
|
||||
|
|
@ -102,18 +79,13 @@ class DialogsHolder {
|
|||
this.isUpdating = true;
|
||||
this.dialogs = [];
|
||||
const end = this.dialogsIterDurationHistogram.startTimer();
|
||||
try {
|
||||
for await (const d of this.tg.iterDialogs()) {
|
||||
if (!peersConfigBoolFilter(config, d.peer.id)) {
|
||||
continue;
|
||||
}
|
||||
this.dialogs.push(d);
|
||||
for await (const d of this.tg.iterDialogs()) {
|
||||
if (!peersConfigBoolFilter(config, d.peer.id)) {
|
||||
continue;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to iterate over telegram dialogs:", e);
|
||||
this.dialogs.push(d);
|
||||
}
|
||||
|
||||
this.dialogsIterDurationSummary.observe(end());
|
||||
end();
|
||||
this.lastUpdate = process.hrtime.bigint();
|
||||
this.isUpdating = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,6 @@ export interface RawKeywordPattern {
|
|||
name: string;
|
||||
pattern: string;
|
||||
word: boolean;
|
||||
flags: {
|
||||
global: boolean;
|
||||
multi_line: boolean;
|
||||
insensitive: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export type RawKeywordLike = string | RawKeywordPattern;
|
||||
|
|
@ -31,7 +26,6 @@ export function rawToPatterns(raw: RawKeywordLike[]): KeywordPattern[] {
|
|||
let pattern;
|
||||
let name;
|
||||
let addBorders = false;
|
||||
let flags = "giu";
|
||||
|
||||
if (typeof keyword === "string") {
|
||||
pattern = escapeRegex(keyword);
|
||||
|
|
@ -41,28 +35,15 @@ export function rawToPatterns(raw: RawKeywordLike[]): KeywordPattern[] {
|
|||
pattern = keyword.pattern;
|
||||
name = keyword.name;
|
||||
addBorders = keyword.word;
|
||||
|
||||
flags = "u";
|
||||
if (keyword.flags.global) {
|
||||
flags += "g";
|
||||
}
|
||||
|
||||
if (keyword.flags.insensitive) {
|
||||
flags += "i";
|
||||
}
|
||||
|
||||
if (keyword.flags.multi_line) {
|
||||
flags += "m";
|
||||
}
|
||||
}
|
||||
|
||||
const wordBorder = escapeRegex("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
|
||||
const borderStart = addBorders ? `(?<=[${wordBorder}\\s]|^)` : "";
|
||||
const borderEnd = addBorders ? `(?=[${wordBorder}\\s]|$)` : "";
|
||||
const borderStart = addBorders ? `(?:[${wordBorder}\\s]|^)` : "";
|
||||
const borderEnd = addBorders ? `(?:[${wordBorder}\\s]|$)` : "";
|
||||
|
||||
patterns.push({
|
||||
name,
|
||||
pattern: new RegExp(`${borderStart}(?:${pattern})${borderEnd}`, flags),
|
||||
pattern: new RegExp(borderStart + pattern + borderEnd),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,71 +2,37 @@ import type { Dispatcher } from "@mtcute/dispatcher";
|
|||
import type { Registry } from "prom-client";
|
||||
|
||||
import { PropagationAction } from "@mtcute/dispatcher";
|
||||
import { Counter, Gauge } from "prom-client";
|
||||
import { Counter } from "prom-client";
|
||||
|
||||
import { config } from "../config.js";
|
||||
import { peersConfigFilter } from "../filters.js";
|
||||
|
||||
export function collectNewMessageMetrics(dp: Dispatcher, registry: Registry) {
|
||||
const sendersMap = new Map<number, string>();
|
||||
const senderInfo = new Gauge({
|
||||
name: "messenger_dialog_sender_info",
|
||||
help: "Sender's information exposed as labels",
|
||||
labelNames: ["senderId", "displayName"],
|
||||
collect: () => {
|
||||
senderInfo.reset();
|
||||
for (const [senderId, displayName] of sendersMap.entries()) {
|
||||
senderInfo.set({ senderId, displayName }, 1);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let labelNames;
|
||||
if (config.messagesCollector.includeSender) {
|
||||
labelNames = ["peerId", "senderId"];
|
||||
} else {
|
||||
labelNames = ["peerId"];
|
||||
}
|
||||
|
||||
const messages = new Counter({
|
||||
name: "messenger_dialog_messages_count",
|
||||
help: "Messages count since exporter startup",
|
||||
labelNames,
|
||||
labelNames: ["peerId"],
|
||||
});
|
||||
|
||||
const media = new Counter({
|
||||
name: "messenger_dialog_media_sent_count",
|
||||
help: "Medias sent since exporter startup",
|
||||
labelNames,
|
||||
labelNames: ["peerId"],
|
||||
});
|
||||
|
||||
const stickers = new Counter({
|
||||
name: "messenger_dialog_stickers_sent_count",
|
||||
help: "Stickers sent since exporter startup",
|
||||
labelNames,
|
||||
labelNames: ["peerId"],
|
||||
});
|
||||
|
||||
const voice = new Counter({
|
||||
name: "messenger_dialog_voice_messages_count",
|
||||
help: "Voice messages sent since exporter startup",
|
||||
labelNames,
|
||||
labelNames: ["peerId"],
|
||||
});
|
||||
|
||||
dp.onNewMessage(peersConfigFilter(config), (msg) => {
|
||||
let labelValues;
|
||||
if (config.messagesCollector.includeSender) {
|
||||
sendersMap.set(msg.sender.id, msg.sender.displayName);
|
||||
|
||||
labelValues = {
|
||||
peerId: msg.chat.id,
|
||||
senderId: msg.sender.id,
|
||||
};
|
||||
} else {
|
||||
labelValues = {
|
||||
peerId: msg.chat.id,
|
||||
};
|
||||
}
|
||||
|
||||
if (msg.media) {
|
||||
let counter;
|
||||
switch (msg.media.type) {
|
||||
|
|
@ -92,17 +58,19 @@ export function collectNewMessageMetrics(dp: Dispatcher, registry: Registry) {
|
|||
}
|
||||
}
|
||||
if (counter) {
|
||||
counter.inc(labelValues);
|
||||
counter.inc({
|
||||
peerId: msg.chat.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
messages.inc(labelValues);
|
||||
messages.inc({
|
||||
peerId: msg.chat.id,
|
||||
});
|
||||
|
||||
return PropagationAction.Continue;
|
||||
});
|
||||
|
||||
if (config.messagesCollector.includeSender) {
|
||||
registry.registerMetric(senderInfo);
|
||||
}
|
||||
registry.registerMetric(media);
|
||||
registry.registerMetric(stickers);
|
||||
registry.registerMetric(voice);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { peersConfigFilter } from "../filters.js";
|
|||
import { collectDialogMetrics } from "./dialogs.js";
|
||||
import { KeywordsCounter } from "./keywords.js";
|
||||
import { collectNewMessageMetrics } from "./message.js";
|
||||
import { collectReactionsMetrics } from "./reactions.js";
|
||||
|
||||
function newWordsCounter(dp: Dispatcher) {
|
||||
const counter = new Counter({
|
||||
|
|
@ -33,7 +32,6 @@ function newWordsCounter(dp: Dispatcher) {
|
|||
export {
|
||||
collectDialogMetrics,
|
||||
collectNewMessageMetrics,
|
||||
collectReactionsMetrics,
|
||||
KeywordsCounter,
|
||||
newWordsCounter,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,213 +0,0 @@
|
|||
import type { Dispatcher } from "@mtcute/dispatcher";
|
||||
import type { TelegramClient, tl } from "@mtcute/node";
|
||||
|
||||
import type { Registry } from "prom-client";
|
||||
import { setTimeout } from "node:timers/promises";
|
||||
import { PropagationAction } from "@mtcute/dispatcher";
|
||||
import { Counter, Gauge } from "prom-client";
|
||||
import { config } from "../config.js";
|
||||
import { peersConfigBoolFilter, peersConfigFilter } from "../filters.js";
|
||||
|
||||
type ReactionsMap = Map<string, number>;
|
||||
type MessageReactionsMap = Map<number, ReactionsMap>;
|
||||
type PeerMessagesMap = Map<number, MessageReactionsMap>;
|
||||
|
||||
function getRawPeerId(peer: tl.TypePeer) {
|
||||
switch (peer._) {
|
||||
case "peerUser": {
|
||||
return peer.userId;
|
||||
}
|
||||
case "peerChat": {
|
||||
return peer.chatId;
|
||||
}
|
||||
case "peerChannel": {
|
||||
return peer.channelId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getRawReactionEmoji(reaction: tl.TypeReaction) {
|
||||
let emojiId: string;
|
||||
let emojiName: string;
|
||||
switch (reaction._) {
|
||||
case "reactionEmoji": {
|
||||
emojiId = reaction.emoticon;
|
||||
emojiName = reaction.emoticon;
|
||||
break;
|
||||
}
|
||||
case "reactionCustomEmoji": {
|
||||
emojiId = `<custom:${reaction.documentId.toString()}>`;
|
||||
emojiName = "<custom>";
|
||||
break;
|
||||
}
|
||||
case "reactionPaid": {
|
||||
emojiId = "<star_paid>";
|
||||
emojiName = "⭐ (Paid)";
|
||||
break;
|
||||
}
|
||||
case "reactionEmpty": {
|
||||
emojiId = "<empty>";
|
||||
emojiName = "<empty>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { id: emojiId, name: emojiName };
|
||||
}
|
||||
|
||||
function getEmojiNameFromId(id: string) {
|
||||
if (id === "<star_paid>") {
|
||||
return "⭐ (Paid)";
|
||||
}
|
||||
if (id.startsWith("<custom:")) {
|
||||
return "<custom>";
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
export async function collectReactionsMetrics(tg: TelegramClient, dp: Dispatcher, registry: Registry) {
|
||||
const peers: PeerMessagesMap = new Map();
|
||||
|
||||
const set = new Counter({
|
||||
name: "messenger_dialog_reactions_set_count",
|
||||
help: "Reactions set count since exporter startup",
|
||||
labelNames: ["peerId", "emoji"],
|
||||
});
|
||||
|
||||
const removed = new Counter({
|
||||
name: "messenger_dialog_reactions_removed_count",
|
||||
help: "Reactions removed count since exporter startup",
|
||||
labelNames: ["peerId", "emoji"],
|
||||
});
|
||||
|
||||
const peersSize = new Gauge({
|
||||
name: "mtproto_exporter_reactions_collector_peers_cache_size",
|
||||
help: "Size of peers cache map size in reactions collector",
|
||||
collect: () => {
|
||||
peersSize.set(peers.size);
|
||||
},
|
||||
});
|
||||
const messagesSize = new Gauge({
|
||||
name: "mtproto_exporter_reactions_collector_messages_cache_size",
|
||||
help: "Size of messages cache map size in reactions collector",
|
||||
collect: () => {
|
||||
messagesSize.reset();
|
||||
for (const m of peers.values()) {
|
||||
messagesSize.inc(m.size);
|
||||
}
|
||||
},
|
||||
});
|
||||
const reactionsSize = new Gauge({
|
||||
name: "mtproto_exporter_reactions_collector_reactions_cache_size",
|
||||
help: "Size of reactions cache map size in reactions collector",
|
||||
collect: () => {
|
||||
reactionsSize.reset();
|
||||
for (const m of peers.values()) {
|
||||
for (const r of m.values()) {
|
||||
reactionsSize.inc(r.size);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
registry.registerMetric(set);
|
||||
registry.registerMetric(removed);
|
||||
registry.registerMetric(peersSize);
|
||||
registry.registerMetric(messagesSize);
|
||||
registry.registerMetric(reactionsSize);
|
||||
|
||||
if (config.reactionsCollector.loadHistory) {
|
||||
console.log("fetching dialogs history into reactions collector cache....");
|
||||
const historyIterOptions = {
|
||||
limit: config.reactionsCollector.loadHistorySize,
|
||||
};
|
||||
for await (const dialog of tg.iterDialogs()) {
|
||||
console.log("fetching dialog with peer id", dialog.peer.id);
|
||||
if (!peersConfigBoolFilter(config, dialog.peer.id)) {
|
||||
continue;
|
||||
}
|
||||
for await (const message of tg.iterHistory(dialog.peer.id, historyIterOptions)) {
|
||||
await handleReactionsUpdate(message.id, dialog.peer.id, message.reactions?.raw.results ?? []);
|
||||
}
|
||||
await setTimeout(5000);
|
||||
}
|
||||
}
|
||||
|
||||
// we need to count only new messages
|
||||
// because we don't know true number of reactions before updates
|
||||
dp.onNewMessage((message) => {
|
||||
const messages: MessageReactionsMap = peers.get(message.chat.id) ?? new Map();
|
||||
const reactions: ReactionsMap = messages.get(message.id) ?? new Map();
|
||||
|
||||
reactions.clear();
|
||||
|
||||
messages.set(message.id, reactions);
|
||||
peers.set(message.chat.id, messages);
|
||||
|
||||
return PropagationAction.Continue;
|
||||
});
|
||||
|
||||
tg.onRawUpdate.add(async (info) => {
|
||||
if ("updates" in info) {
|
||||
const updates = info.updates as tl.TypeUpdate[];
|
||||
const reactionsUpdates = updates.filter(u => u._ === "updateMessageReactions");
|
||||
for (const update of reactionsUpdates) {
|
||||
await handleReactionsUpdate(update.msgId, getRawPeerId(update.peer), update.reactions.results);
|
||||
}
|
||||
} else if (info.update && info.update._ === "updateMessageReactions") {
|
||||
await handleReactionsUpdate(info.update.msgId, getRawPeerId(info.update.peer), info.update.reactions.results);
|
||||
}
|
||||
});
|
||||
|
||||
dp.onEditMessage(peersConfigFilter(config), async (message) => {
|
||||
if (!message.reactions || !message.reactions.reactions) {
|
||||
return;
|
||||
}
|
||||
await handleReactionsUpdate(message.id, message.chat.id, message.reactions.raw.results);
|
||||
return PropagationAction.Continue;
|
||||
});
|
||||
|
||||
async function handleReactionsUpdate(messageId: number, peerId: number, reactions: tl.RawReactionCount[]) {
|
||||
const peer: MessageReactionsMap = peers.get(peerId) ?? new Map();
|
||||
const oldReactions = peer.get(messageId);
|
||||
|
||||
const newReactions = new Map<string, number>();
|
||||
for (const r of reactions) {
|
||||
const emoji = getRawReactionEmoji(r.reaction);
|
||||
newReactions.set(emoji.id, r.count);
|
||||
}
|
||||
|
||||
if (!oldReactions) {
|
||||
peer.set(messageId, newReactions);
|
||||
peers.set(peerId, peer);
|
||||
return;
|
||||
}
|
||||
|
||||
const allReactions = new Set<string>([
|
||||
...newReactions.keys(),
|
||||
...oldReactions.keys(),
|
||||
]);
|
||||
|
||||
for (const r of allReactions) {
|
||||
const countBefore = oldReactions.get(r) ?? 0;
|
||||
const countAfter = newReactions.get(r) ?? 0;
|
||||
const diff = countAfter - countBefore;
|
||||
|
||||
if (diff > 0) {
|
||||
set.inc({
|
||||
peerId,
|
||||
emoji: getEmojiNameFromId(r),
|
||||
});
|
||||
} else if (diff < 0) {
|
||||
removed.inc({
|
||||
peerId,
|
||||
emoji: getEmojiNameFromId(r),
|
||||
});
|
||||
}
|
||||
|
||||
oldReactions.set(r, countAfter);
|
||||
}
|
||||
|
||||
peer.set(messageId, oldReactions);
|
||||
peers.set(peerId, peer);
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ export default class MetricsServer {
|
|||
|
||||
private async _requestHandler(req: http.IncomingMessage, res: http.ServerResponse) {
|
||||
const url = new URL(`http://${req.headers.host ?? "localhost"}${req.url}`);
|
||||
console.log(`[HTTP] ${req.method} - ${req.socket.localAddress}:${req.socket.localPort} (${url.href}) from ${req.socket.remoteAddress}:${req.socket.remotePort}`);
|
||||
console.log(`[HTTP] ${req.method} - ${url.href} from ${req.socket.remoteAddress}:${req.socket.remotePort}`);
|
||||
|
||||
if (req.method === "GET" && url.pathname === "/metrics") {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue