GochoMugo / tgfancy

A Fancy, Higher-Level Wrapper for Telegram Bot API
MIT License
184 stars 16 forks source link

Telegram sendMessage limit handling #4

Closed iMasoud closed 7 years ago

iMasoud commented 7 years ago

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.

kamikazechaser commented 7 years ago

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!

GochoMugo commented 7 years ago

@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:

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!

iMasoud commented 7 years ago

@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?

kamikazechaser commented 7 years ago

@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

GochoMugo commented 7 years ago

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.

GochoMugo commented 7 years ago

Rate-limiting fanciness added in v0.7.0.

See the docs.