mirror of
https://github.com/flibusta-apps/book_bot.git
synced 2025-12-06 15:35:35 +01:00
Add limiter
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { Context } from "telegraf";
|
import { Context } from "telegraf";
|
||||||
import { AuthorAnnnotation, BookAnnotation } from "./services/book_library";
|
import { AuthorAnnotation, BookAnnotation } from "./services/book_library";
|
||||||
|
|
||||||
import { isNormalText } from "./utils";
|
import { isNormalText } from "./utils";
|
||||||
import { getTextPaginationData } from './keyboard';
|
import { getTextPaginationData } from './keyboard';
|
||||||
@@ -7,7 +7,7 @@ import Sentry from '@/sentry';
|
|||||||
import { downloadImage } from "./services/downloader";
|
import { downloadImage } from "./services/downloader";
|
||||||
|
|
||||||
|
|
||||||
export function getAnnotationHandler<T extends BookAnnotation | AuthorAnnnotation>(
|
export function getAnnotationHandler<T extends BookAnnotation | AuthorAnnotation>(
|
||||||
annotationGetter: (id: number) => Promise<T>,
|
annotationGetter: (id: number) => Promise<T>,
|
||||||
callbackData: string
|
callbackData: string
|
||||||
): (ctx: Context) => Promise<void> {
|
): (ctx: Context) => Promise<void> {
|
||||||
@@ -32,7 +32,6 @@ export function getAnnotationHandler<T extends BookAnnotation | AuthorAnnnotatio
|
|||||||
try {
|
try {
|
||||||
await ctx.telegram.sendPhoto(ctx.message.chat.id, { source: imageData });
|
await ctx.telegram.sendPhoto(ctx.message.chat.id, { source: imageData });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
|
||||||
Sentry.captureException(e);
|
Sentry.captureException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import * as CallbackData from "./callback_data";
|
|||||||
import * as BookLibrary from "./services/book_library";
|
import * as BookLibrary from "./services/book_library";
|
||||||
import * as Rating from "./services/book_ratings";
|
import * as Rating from "./services/book_ratings";
|
||||||
import UsersCounter from '@/analytics/users_counter';
|
import UsersCounter from '@/analytics/users_counter';
|
||||||
|
import Limiter from '@/bots/limiter';
|
||||||
import { createOrUpdateUserSettings, getUserOrDefaultLangCodes } from './services/user_settings';
|
import { createOrUpdateUserSettings, getUserOrDefaultLangCodes } from './services/user_settings';
|
||||||
import { formatBook, formatBookShort, formatAuthor, formatSequence, formatTranslator, formatDetailBook, formatDetailBookWithRating } from './format';
|
import { formatBook, formatBookShort, formatAuthor, formatSequence, formatTranslator, formatDetailBook, formatDetailBookWithRating } from './format';
|
||||||
import { getCallbackArgs, getPaginatedMessage, getPrefixWithQueryCreator, getSearchArgs, registerLanguageSettingsCallback, registerPaginationCommand, registerRandomItemCallback } from './utils';
|
import { getCallbackArgs, getPaginatedMessage, getPrefixWithQueryCreator, getSearchArgs, registerLanguageSettingsCallback, registerPaginationCommand, registerRandomItemCallback } from './utils';
|
||||||
@@ -54,6 +55,12 @@ export async function createApprovedBot(token: string, state: BotState): Promise
|
|||||||
await next();
|
await next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bot.use(async (ctx: Context, next) => {
|
||||||
|
if (await Limiter.isLimited(ctx.update.update_id)) return;
|
||||||
|
|
||||||
|
await next();
|
||||||
|
});
|
||||||
|
|
||||||
bot.command(["start", `start@${me.username}`], async (ctx: Context) => {
|
bot.command(["start", `start@${me.username}`], async (ctx: Context) => {
|
||||||
if (!ctx.message) {
|
if (!ctx.message) {
|
||||||
return;
|
return;
|
||||||
@@ -449,7 +456,7 @@ export async function createApprovedBot(token: string, state: BotState): Promise
|
|||||||
});
|
});
|
||||||
|
|
||||||
bot.catch((err, ctx: Context) => {
|
bot.catch((err, ctx: Context) => {
|
||||||
console.log(err, ctx);
|
console.log({err, ctx});
|
||||||
Sentry.captureException(err);
|
Sentry.captureException(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export interface Sequence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface AuthorAnnnotation {
|
export interface AuthorAnnotation {
|
||||||
id: number;
|
id: number;
|
||||||
title: string;
|
title: string;
|
||||||
text: string;
|
text: string;
|
||||||
|
|||||||
46
src/bots/limiter/index.ts
Normal file
46
src/bots/limiter/index.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { createClient, RedisClientType } from 'redis';
|
||||||
|
|
||||||
|
import env from '@/config';
|
||||||
|
|
||||||
|
import Sentry from '@/sentry';
|
||||||
|
|
||||||
|
|
||||||
|
export default class Limiter {
|
||||||
|
static MAX_PROCESSING_COUNT: number = 3;
|
||||||
|
static _redisClient: RedisClientType | null = null;
|
||||||
|
|
||||||
|
static async _getClient() {
|
||||||
|
if (this._redisClient === null) {
|
||||||
|
this._redisClient = createClient({
|
||||||
|
url: `redis://${env.REDIS_HOST}:${env.REDIS_PORT}/${env.REDIS_DB}`
|
||||||
|
});
|
||||||
|
|
||||||
|
this._redisClient.on('error', (err) => {
|
||||||
|
console.log(err);
|
||||||
|
Sentry.captureException(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
await this._redisClient.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._redisClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _getKey(updateId: number) {
|
||||||
|
return `update_${updateId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async _getCount(updateId: number): Promise<number> {
|
||||||
|
const key = this._getKey(updateId);
|
||||||
|
|
||||||
|
const client = await this._getClient();
|
||||||
|
|
||||||
|
await client.set(key, 0, {EX: 5 * 60, NX: true});
|
||||||
|
return client.incr(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async isLimited(updateId: number): Promise<boolean> {
|
||||||
|
const count = await this._getCount(updateId);
|
||||||
|
return count <= this.MAX_PROCESSING_COUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user