feat: add rate limiting functionality to bot; update localization files for limit exceeded messages in English and Russian
This commit is contained in:
parent
ae48a23896
commit
00dab85d2f
@ -1,3 +1,4 @@
|
|||||||
invalid_url = Invalid url
|
invalid_url = Invalid url
|
||||||
invalid_download_urls = download urls not found
|
invalid_download_urls = download urls not found
|
||||||
generic = Something went wrong
|
generic = Something went wrong
|
||||||
|
limit_exceeded = Please stop spaming!
|
||||||
@ -1,3 +1,4 @@
|
|||||||
invalid_url = Неверная ссылка
|
invalid_url = Неверная ссылка
|
||||||
invalid_download_urls = Не найдены ссылки для скачивания
|
invalid_download_urls = Не найдены ссылки для скачивания
|
||||||
generic = Что-то пошло не так
|
generic = Что-то пошло не так
|
||||||
|
limit_exceeded = Пожалуйста, прекратите спамить!
|
||||||
@ -22,6 +22,7 @@
|
|||||||
"@grammyjs/hydrate": "^1.4.1",
|
"@grammyjs/hydrate": "^1.4.1",
|
||||||
"@grammyjs/i18n": "^1.1.2",
|
"@grammyjs/i18n": "^1.1.2",
|
||||||
"@grammyjs/parse-mode": "^2.2.0",
|
"@grammyjs/parse-mode": "^2.2.0",
|
||||||
|
"@grammyjs/ratelimiter": "^1.2.1",
|
||||||
"@grammyjs/types": "^3.21.0",
|
"@grammyjs/types": "^3.21.0",
|
||||||
"@repo/typescript-config": "workspace:*",
|
"@repo/typescript-config": "workspace:*",
|
||||||
"@tobyg74/tiktok-api-dl": "^1.3.4",
|
"@tobyg74/tiktok-api-dl": "^1.3.4",
|
||||||
|
|||||||
@ -3,9 +3,12 @@ import { type Context } from './context';
|
|||||||
import * as features from './features';
|
import * as features from './features';
|
||||||
import { errorHandler } from './handlers/errors';
|
import { errorHandler } from './handlers/errors';
|
||||||
import { i18n } from './i18n';
|
import { i18n } from './i18n';
|
||||||
|
import { env } from '@/config/env';
|
||||||
import { logger } from '@/utils/logger';
|
import { logger } from '@/utils/logger';
|
||||||
|
import { getRedisInstance } from '@/utils/redis';
|
||||||
import { autoChatAction } from '@grammyjs/auto-chat-action';
|
import { autoChatAction } from '@grammyjs/auto-chat-action';
|
||||||
import { hydrate } from '@grammyjs/hydrate';
|
import { hydrate } from '@grammyjs/hydrate';
|
||||||
|
import { limit } from '@grammyjs/ratelimiter';
|
||||||
import { Bot } from 'grammy';
|
import { Bot } from 'grammy';
|
||||||
|
|
||||||
type Parameters_ = {
|
type Parameters_ = {
|
||||||
@ -13,6 +16,8 @@ type Parameters_ = {
|
|||||||
token: string;
|
token: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const redis = getRedisInstance();
|
||||||
|
|
||||||
export function createBot({ apiRoot, token }: Parameters_) {
|
export function createBot({ apiRoot, token }: Parameters_) {
|
||||||
const bot = new Bot<Context>(token, {
|
const bot = new Bot<Context>(token, {
|
||||||
client: {
|
client: {
|
||||||
@ -20,6 +25,22 @@ export function createBot({ apiRoot, token }: Parameters_) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bot.use(i18n);
|
||||||
|
|
||||||
|
bot.use(
|
||||||
|
limit({
|
||||||
|
keyGenerator: (ctx) => {
|
||||||
|
return ctx.from?.id.toString();
|
||||||
|
},
|
||||||
|
limit: 1,
|
||||||
|
onLimitExceeded: async (ctx) => {
|
||||||
|
await ctx.reply(ctx.t('limit_exceeded'));
|
||||||
|
},
|
||||||
|
storageClient: redis,
|
||||||
|
timeFrame: env.RATE_LIMIT,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
bot.use(async (context, next) => {
|
bot.use(async (context, next) => {
|
||||||
context.logger = logger.child({
|
context.logger = logger.child({
|
||||||
update_id: context.update.update_id,
|
update_id: context.update.update_id,
|
||||||
@ -30,7 +51,6 @@ export function createBot({ apiRoot, token }: Parameters_) {
|
|||||||
|
|
||||||
const protectedBot = bot.errorBoundary(errorHandler);
|
const protectedBot = bot.errorBoundary(errorHandler);
|
||||||
|
|
||||||
protectedBot.use(i18n);
|
|
||||||
protectedBot.use(autoChatAction(bot.api));
|
protectedBot.use(autoChatAction(bot.api));
|
||||||
protectedBot.use(hydrate());
|
protectedBot.use(hydrate());
|
||||||
protectedBot.use(features.download);
|
protectedBot.use(features.download);
|
||||||
|
|||||||
@ -3,6 +3,10 @@ import { z } from 'zod';
|
|||||||
|
|
||||||
export const envSchema = z.object({
|
export const envSchema = z.object({
|
||||||
BOT_TOKEN: z.string(),
|
BOT_TOKEN: z.string(),
|
||||||
|
RATE_LIMIT: z
|
||||||
|
.string()
|
||||||
|
.transform((value) => Number.parseInt(value, 10))
|
||||||
|
.default('5000'),
|
||||||
REDIS_HOST: z.string(),
|
REDIS_HOST: z.string(),
|
||||||
REDIS_PASSWORD: z.string(),
|
REDIS_PASSWORD: z.string(),
|
||||||
REDIS_PORT: z
|
REDIS_PORT: z
|
||||||
|
|||||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@ -66,6 +66,9 @@ importers:
|
|||||||
'@grammyjs/parse-mode':
|
'@grammyjs/parse-mode':
|
||||||
specifier: ^2.2.0
|
specifier: ^2.2.0
|
||||||
version: 2.2.0(grammy@1.37.1)
|
version: 2.2.0(grammy@1.37.1)
|
||||||
|
'@grammyjs/ratelimiter':
|
||||||
|
specifier: ^1.2.1
|
||||||
|
version: 1.2.1
|
||||||
'@grammyjs/types':
|
'@grammyjs/types':
|
||||||
specifier: ^3.21.0
|
specifier: ^3.21.0
|
||||||
version: 3.21.0
|
version: 3.21.0
|
||||||
@ -516,6 +519,9 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
grammy: ^1.36.1
|
grammy: ^1.36.1
|
||||||
|
|
||||||
|
'@grammyjs/ratelimiter@1.2.1':
|
||||||
|
resolution: {integrity: sha512-4bmVUBCBnIb2epbDiBLCvvnVjaYg7kDCPR1Ptt6gqoxm5vlD8BjainYv+yjF6221hu2KUv8QAckumDI+6xyGsQ==}
|
||||||
|
|
||||||
'@grammyjs/types@3.21.0':
|
'@grammyjs/types@3.21.0':
|
||||||
resolution: {integrity: sha512-IMj0EpmglPCICuyfGRx4ENKPSuzS2xMSoPgSPzHC6FtnWKDEmJLBP/GbPv/h3TAeb27txqxm/BUld+gbJk6ccQ==}
|
resolution: {integrity: sha512-IMj0EpmglPCICuyfGRx4ENKPSuzS2xMSoPgSPzHC6FtnWKDEmJLBP/GbPv/h3TAeb27txqxm/BUld+gbJk6ccQ==}
|
||||||
|
|
||||||
@ -4290,6 +4296,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
grammy: 1.37.1
|
grammy: 1.37.1
|
||||||
|
|
||||||
|
'@grammyjs/ratelimiter@1.2.1': {}
|
||||||
|
|
||||||
'@grammyjs/types@3.21.0': {}
|
'@grammyjs/types@3.21.0': {}
|
||||||
|
|
||||||
'@graphql-eslint/eslint-plugin@4.4.0(@types/node@24.3.0)(eslint@9.33.0(jiti@2.5.1))(graphql@16.11.0)(typescript@5.9.2)':
|
'@graphql-eslint/eslint-plugin@4.4.0(@types/node@24.3.0)(eslint@9.33.0(jiti@2.5.1))(graphql@16.11.0)(typescript@5.9.2)':
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user