docker-compose: add Redis service and update bot configuration for caching; integrate Redis in download feature for improved performance
This commit is contained in:
parent
0b6c4427c9
commit
463bdfd089
@ -27,8 +27,9 @@
|
||||
"@tobyg74/tiktok-api-dl": "^1.3.4",
|
||||
"@types/node": "catalog:",
|
||||
"grammy": "^1.37.0",
|
||||
"pino-pretty": "^13.1.1",
|
||||
"ioredis": "^5.7.0",
|
||||
"pino": "^9.9.0",
|
||||
"pino-pretty": "^13.1.1",
|
||||
"tsup": "^8.5.0",
|
||||
"typescript": "catalog:",
|
||||
"zod": "catalog:"
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
/* eslint-disable consistent-return */
|
||||
import { type Context } from '../context';
|
||||
import { logHandle } from '../helpers/logging';
|
||||
import { TTL } from '@/config/redis';
|
||||
import { createRedisInstance } from '@/utils/redis';
|
||||
import { validateTikTokUrl } from '@/utils/urls';
|
||||
import { Downloader } from '@tobyg74/tiktok-api-dl';
|
||||
import { Composer, InputFile } from 'grammy';
|
||||
@ -9,12 +11,18 @@ const composer = new Composer<Context>();
|
||||
|
||||
const feature = composer.chatType('private');
|
||||
|
||||
const redis = createRedisInstance();
|
||||
|
||||
feature.on('message:text', logHandle('download-message'), async (context) => {
|
||||
try {
|
||||
const url = context.message.text;
|
||||
const url = context.message.text.trim();
|
||||
|
||||
if (!validateTikTokUrl(url)) return context.reply(context.t('invalid_url'));
|
||||
|
||||
const cachedFileId = await redis.get(url);
|
||||
|
||||
if (cachedFileId) return context.replyWithVideo(cachedFileId);
|
||||
|
||||
const { message, result } = await Downloader(url, { version: 'v3' });
|
||||
|
||||
if (message) throw new Error(message);
|
||||
@ -27,7 +35,9 @@ feature.on('message:text', logHandle('download-message'), async (context) => {
|
||||
}
|
||||
|
||||
if (result?.type === 'video' && videoUrl) {
|
||||
return context.replyWithVideo(new InputFile({ url: videoUrl }));
|
||||
const { video } = await context.replyWithVideo(new InputFile({ url: videoUrl }));
|
||||
|
||||
await redis.set(url, video.file_id, 'EX', TTL);
|
||||
}
|
||||
|
||||
if (result?.type === 'image' && imagesUrls) {
|
||||
|
||||
@ -3,6 +3,12 @@ import { z } from 'zod';
|
||||
|
||||
export const envSchema = z.object({
|
||||
BOT_TOKEN: z.string(),
|
||||
REDIS_HOST: z.string(),
|
||||
REDIS_PASSWORD: z.string(),
|
||||
REDIS_PORT: z
|
||||
.string()
|
||||
.transform((value) => Number.parseInt(value, 10))
|
||||
.default('6379'),
|
||||
TELEGRAM_API_ROOT: z.string(),
|
||||
});
|
||||
|
||||
|
||||
1
apps/bot/src/config/redis.ts
Normal file
1
apps/bot/src/config/redis.ts
Normal file
@ -0,0 +1 @@
|
||||
export const TTL = 12 * 60 * 60; // 12 hours in seconds
|
||||
15
apps/bot/src/utils/redis.ts
Normal file
15
apps/bot/src/utils/redis.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { env } from '@/config/env';
|
||||
import { logger } from '@/utils/logger';
|
||||
import Redis from 'ioredis';
|
||||
|
||||
export function createRedisInstance() {
|
||||
const redis = new Redis({
|
||||
host: env.REDIS_HOST,
|
||||
password: env.REDIS_PASSWORD,
|
||||
port: env.REDIS_PORT,
|
||||
});
|
||||
|
||||
redis.on('error', logger.error);
|
||||
|
||||
return redis;
|
||||
}
|
||||
@ -1,4 +1,29 @@
|
||||
services:
|
||||
redis:
|
||||
env_file:
|
||||
- .env
|
||||
image: redis:8-alpine
|
||||
restart: always
|
||||
ports:
|
||||
- "127.0.0.1:6379:6379"
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.50'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.25'
|
||||
memory: 256M
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
next-downloader-bot:
|
||||
env_file:
|
||||
- .env
|
||||
@ -6,6 +31,9 @@ services:
|
||||
context: .
|
||||
dockerfile: ./apps/bot/Dockerfile
|
||||
restart: always
|
||||
depends_on:
|
||||
- redis
|
||||
|
||||
telegram-bot-api:
|
||||
env_file:
|
||||
- .env
|
||||
@ -15,8 +43,9 @@ services:
|
||||
# TELEGRAM_API_HASH: "<api-hash>"
|
||||
volumes:
|
||||
- telegram-bot-api-data:/var/lib/telegram-bot-api
|
||||
# ports:
|
||||
# - "8081:8081"
|
||||
ports:
|
||||
- "127.0.0.1:8081:8081"
|
||||
|
||||
volumes:
|
||||
telegram-bot-api-data:
|
||||
redis-data:
|
||||
|
||||
67
pnpm-lock.yaml
generated
67
pnpm-lock.yaml
generated
@ -81,6 +81,9 @@ importers:
|
||||
grammy:
|
||||
specifier: ^1.37.0
|
||||
version: 1.37.1
|
||||
ioredis:
|
||||
specifier: ^5.7.0
|
||||
version: 5.7.0
|
||||
pino:
|
||||
specifier: ^9.9.0
|
||||
version: 9.9.0
|
||||
@ -673,6 +676,9 @@ packages:
|
||||
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
|
||||
engines: {node: '>=18.18'}
|
||||
|
||||
'@ioredis/commands@1.3.0':
|
||||
resolution: {integrity: sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
@ -1331,6 +1337,10 @@ packages:
|
||||
resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
cluster-key-slot@1.1.2:
|
||||
resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
@ -1499,6 +1509,10 @@ packages:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
denque@2.1.0:
|
||||
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
detect-libc@2.0.4:
|
||||
resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==}
|
||||
engines: {node: '>=8'}
|
||||
@ -2367,6 +2381,10 @@ packages:
|
||||
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
ioredis@5.7.0:
|
||||
resolution: {integrity: sha512-NUcA93i1lukyXU+riqEyPtSEkyFq8tX90uL659J+qpCZ3rEdViB/APC58oAhIh3+bJln2hzdlZbBZsGNrlsR8g==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
|
||||
ip-address@10.0.1:
|
||||
resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==}
|
||||
engines: {node: '>= 12'}
|
||||
@ -2657,10 +2675,16 @@ packages:
|
||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
lodash.defaults@4.2.0:
|
||||
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
|
||||
|
||||
lodash.get@4.4.2:
|
||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||
deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
|
||||
|
||||
lodash.isarguments@3.1.0:
|
||||
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
|
||||
|
||||
lodash.lowercase@4.3.0:
|
||||
resolution: {integrity: sha512-UcvP1IZYyDKyEL64mmrwoA1AbFu5ahojhTtkOUr1K9dbuxzS9ev8i4TxMMGCqRC9TE8uDaSoufNAXxRPNTseVA==}
|
||||
|
||||
@ -3180,6 +3204,14 @@ packages:
|
||||
resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
redis-errors@1.2.0:
|
||||
resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
redis-parser@3.0.0:
|
||||
resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
refa@0.12.1:
|
||||
resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==}
|
||||
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
|
||||
@ -3422,6 +3454,9 @@ packages:
|
||||
stable-hash@0.0.5:
|
||||
resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==}
|
||||
|
||||
standard-as-callback@2.1.0:
|
||||
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -4501,6 +4536,8 @@ snapshots:
|
||||
|
||||
'@humanwhocodes/retry@0.4.3': {}
|
||||
|
||||
'@ioredis/commands@1.3.0': {}
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
@ -5201,6 +5238,8 @@ snapshots:
|
||||
slice-ansi: 5.0.0
|
||||
string-width: 7.2.0
|
||||
|
||||
cluster-key-slot@1.1.2: {}
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
@ -5348,6 +5387,8 @@ snapshots:
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
denque@2.1.0: {}
|
||||
|
||||
detect-libc@2.0.4: {}
|
||||
|
||||
didyoumean@1.2.2: {}
|
||||
@ -6465,6 +6506,20 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
side-channel: 1.1.0
|
||||
|
||||
ioredis@5.7.0:
|
||||
dependencies:
|
||||
'@ioredis/commands': 1.3.0
|
||||
cluster-key-slot: 1.1.2
|
||||
debug: 4.4.1
|
||||
denque: 2.1.0
|
||||
lodash.defaults: 4.2.0
|
||||
lodash.isarguments: 3.1.0
|
||||
redis-errors: 1.2.0
|
||||
redis-parser: 3.0.0
|
||||
standard-as-callback: 2.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
ip-address@10.0.1: {}
|
||||
|
||||
is-array-buffer@3.0.5:
|
||||
@ -6778,8 +6833,12 @@ snapshots:
|
||||
dependencies:
|
||||
p-locate: 5.0.0
|
||||
|
||||
lodash.defaults@4.2.0: {}
|
||||
|
||||
lodash.get@4.4.2: {}
|
||||
|
||||
lodash.isarguments@3.1.0: {}
|
||||
|
||||
lodash.lowercase@4.3.0: {}
|
||||
|
||||
lodash.merge@4.6.2: {}
|
||||
@ -7281,6 +7340,12 @@ snapshots:
|
||||
tiny-invariant: 1.3.3
|
||||
tslib: 2.8.1
|
||||
|
||||
redis-errors@1.2.0: {}
|
||||
|
||||
redis-parser@3.0.0:
|
||||
dependencies:
|
||||
redis-errors: 1.2.0
|
||||
|
||||
refa@0.12.1:
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
@ -7562,6 +7627,8 @@ snapshots:
|
||||
|
||||
stable-hash@0.0.5: {}
|
||||
|
||||
standard-as-callback@2.1.0: {}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user