I have a telegram bot that for any received message runs a program in the server and sends its result back. But there is a problem! If a user sends too many messages to my bot(spamming), it will make server so busy!
Is there any way to block the people whom send more than 5 messages in a second and don't receive their messages anymore? (using telegram api!!)

- 164
- 1
- 1
- 13
-
No, you can't. API does not provide this feature. Just make a local block list of users whom the bot will ignore. – mymedia Mar 19 '17 at 11:23
-
I want those users' messages don't even exist in the json file which I download from telegram server! Anyway, it's ok if there is no other way. – MaGaroo Mar 19 '17 at 11:31
3 Answers
Firstly I have to say that Telegram Bot API does not have such a capability itself, Therefore you will need to implement it on your own and all you need to do is:
- Count the number of the messages that a user sends within a second which won't be so easy without having a database. But if you have a database with a table called Black_List and save all the messages with their sent-time in another table, you'll be able to count the number of messages sent via one specific ChatID in a pre-defined time period(In your case; 1 second) and check if the count is bigger than 5 or not, if the answer was YES you can insert that ChatID to the Black_List table.
Every time the bot receives a message it must run a database query to see that the sender's chatID exists in the Black_List table or not. If it exists it should continue its own job and ignore the message(Or even it can send an alert to the user saying: "You're blocked." which I think can be time consuming).
Note that as I know the current telegram bot API doesn't have the feature to stop receiving messages but as I mentioned above you can ignore the messages from spammers.
In order to save time, You should avoid making a database connection every time the bot receives an update(message), instead you can load the ChatIDs that exist in the Black_List to a DataSet and update the DataSet right after the insertion of a new spammer ChatID to the Black_List table. This way the number of the queries will reduce noticeably.

- 1,680
- 2
- 24
- 47

- 1,341
- 1
- 12
- 35
-
-
1@Naser.Sadeghi but we can still ban a user in a supergroup/channel, according to https://core.telegram.org/method/channels.editBanned, right? – stckvrw Jan 18 '22 at 13:00
-
I have achieved it by this mean:
# Using the ttlcache to set a time-limited dict. you can adjust the ttl.
ttl_cache = cachetools.TTLCache(maxsize=128, ttl=60)
def check_user_msg_frequency(message):
print(ttl_cache)
msg_cnt = ttl_cache[message.from_user.id]
if msg_cnt > 3:
now = datetime.now()
until = now + timedelta(seconds=60*10)
bot.restrict_chat_member(message.chat.id, message.from_user.id, until_date=until)
def set_user_msg_frequency(message):
if not ttl_cache.get(message.from_user.id):
ttl_cache[message.from_user.id] = 1
else:
ttl_cache[message.from_user.id] += 1
With these to functions above, you can record how many messages sent by any user in the period. If a user's messages sent more than expected, he would be restricted.
Then, every handler you called should call these two functions:
@bot.message_handler(commands=['start', 'help'])
def handle_start_help(message):
set_user_msg_frequency(message)
check_user_msg_frequency(message)
I'm using pyTelegramBotAPI
this module to handle.

- 3,915
- 6
- 30
- 66
I know I'm late to the party, but here is another simple solution that doesn't use a Db:
Create a ConversationState class to attach to each telegram Id when they start to chat with the bot
Then add a LastMessage DateTime variable to the ConversationState class
Now every time you receive a message check if enought time has passed from the LasteMessage DateTime, if not enought time has passed answer with a warning message.
You can also implement a timer that deletes the conversation state class if you are worried about performance.
-
Parties are good even if you arrive a bit late. XD However, I was wondering although this solution works for a small bot, it's against the factors of [12-factor app](https://12factor.net/) and therefore not so scalable. – MaGaroo Jan 24 '23 at 22:43
-
@MaGaroo against which factor would it be? Wouldn't checking a simple hash map for each message be more efficent than doing a query ( as suggested in the highest answer)? – milo brontesi Jan 26 '23 at 08:46
-
Of course that's more efficient, but it's against "Execute the app as one or more stateless processes" rule as mentioned [here](https://12factor.net/processes). That's because defining `ConversationState` makes the process stateful, and we won't be able to scale the number of processes. It's impossible to share this dictionary among multiple processes without a backing service, and if we don't share it, there may be odd situations in which a process has blocked a user and another one hasn't. – MaGaroo Jan 30 '23 at 05:06