GochoMugo / tgfancy

A Fancy, Higher-Level Wrapper for Telegram Bot API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Telegram sendMessage limit handling

iMasoud opened this issue · comments

Hi,

This module is very interesting to me. But I'm wondering if it's able to handle sendMessage limits of telegram?
I mean if I call sendMessage 31 times in a second, will it manage to execute first 30 in same second and execute the 31st in next?

I have the same question about two other limits of telegram which are; sending only one message per second to same chat id and sending 20 messages per second (at most) to same group.

Hi,

This module does not feature a rate-limiting feature yet. That means you will have to implemement it yourself for now. Telegram claims a max of 30 calls/sec however you can get 429 errors below or above that value.
Tgfancy features a Order sending feature that calls a method in the order you define (see example).
Also note that all Telegram methods are subject to rate limiting.

In the meanwhile we can wait to see if @GochoMugo will add a new rate-limiting fanciness!

@iMasoud: Thanks for your interest in this library. Hope it helps you build better bots.
@kamikazechaser: Thanks for addressing the issue.

We can add this new fanciness:

rate-limiting:

On rate-limit errors, we receive error_code set to 429 (see Telegram docs). We are sure that our request had no effect on the implied state between the Telegram servers and the bot. We are free (and actually recommended) to repeat our request at a later time.

Currently, node-telegram-bot-api does passes us a generic Error object in the .catch() handler of our request promises. We need to parse the error's message to figure out the error code. (We need to improve the library to pass a proper error object, with important information readily available for consumers! A PR be expected there!)

My approach in implementing this feature:

  • wrap our requests in a promise that, on error, only rejects if the error is not due to rate-limiting. Otherwise, we wait for the recommended time before retrying the request.
  • we should keep retrying the request until we succeed or a maximum number of retries is exceeded, whichever comes first
  • this should be completely transparent and the user should not even realize we hit a rate-limiting issue (unless max retries!)

You (@kamikazechaser) might realize that I have decided not to use a rate-limiting library, like node-rate-limiter or pothole. I feel that would add too much complexity in the implementation. However, after the above suggested implementation has been worked out, we will consider including such capabilities within!

I will work on this asap!

@kamikazechaser: Thanks for your reply.
What did you mean by that (Also note that all Telegram methods are subject to rate limiting.) part? I didn't see any limits on telegram bot API docs except for sendMessage method.

@GochoMugo: Your concept sounds great. I can't wait to see it implemented!
But until then, would you suggest me to use one of those two mentioned modules to avoid hitting telegram limits? Or you would suggest me to make some kind of deligate myself for it?

@iMasoud The findings were made by the writer of GroupButler, who also was among the first to unofficially document the various error codes not found in the official docs.

C.C @RememberTheAir

So, in the mean time, you might use pothole, in this way:

const pothole = require("pothole");

// creating a rate-limiter to use for the Telegram Bot API
pothole.add("TelegramBotAPI", {
    window: {
        size: 30,           // 30 requests...
        length: 1000,       // ...in 1 second (1000 ms)
    },
});


// the function that you will use instead of 'TelegramBot#sendMessage()'
function sendMessage(chatId, text) {
    return new Promise(function(resolve, reject) {
        pothole.enqueue("TelegramBotAPI", function() {
            bot.sendMessage(chatId, text).then(resolve).catch(reject);
        });
    });
}

// sending a message
sendMessage(chatId, text);

Note that the above solution does not take into account any other
requests made against the API, such as bot.sendPhoto(), etc.

Rate-limiting fanciness added in v0.7.0.

See the docs.