Telegram bot api: Error code 429, Error: Too many requests: retry later
Asked Answered
T

7

28

We have a Telegram bot. It has around 1.2 million subscribers.

Now we're facing a problem in sending messages to these number of subscribers.

Telegram bot API does not provide any batch message functionality and we'd have to send individual requests to Telegram. The problem is, after a few thousand messages, Telegram starts responding with Error 429: too many requests, and does not accept any requests for a while.

How can we effectively message our subscribers?

Tevis answered 10/8, 2015 at 7:39 Comment(2)
1.2 Million subscribers ?! bot name ? :) As noted by @user3313781 answer, Telegram bot servers use this "antispam" limit startegy, at the moment. Do you solved sending message in a opportune bigger time elapse? By example sending each message every max 50 milliseconds ?Saiz
This was short before channels were introduced in Sept. 2015. Today you should send to channels and not via private messageForepleasure
C
13

You should simply implement a global rate limiter to ensure no single user gets above a fixed number of messages per second. to be safe, set your limiter at lower than 30, maybe even to 5 msgs per second.

Really anything higher than 5 messages per second to a single user quickly becomes an annoyance.

cheers.

Conchita answered 21/1, 2016 at 15:11 Comment(3)
What can be the reason if I get this error as well but only if I try to sendContact via telegram. I am using Telegraf Framework. I don't have subscribers now. Just learning the framework. What can make a loop what I could miss?Misdemean
@Valaryo It feels like Telegram has another rate limit only for sending contacts. It might not even be on purpose, as this is not so common.Chiseler
When the error message says "retry after N" (e.g. "retry after 23"), does anybody know what units N is in? Seconds? Milliseconds??Population
F
11

I'm the owner of Ramona Bot. There is a limit for sending message to users. as they said ~30 message per second. Otherwise you will get that Error 429.

Fauman answered 2/10, 2015 at 11:20 Comment(1)
Do you maybe tested what happens after having received an Error 429 ? Do you solved sending messages in a opportune time elapse (after the 429 Reject) sending each message every max 50 milliseconds ? Do you used maybe and output message queue ? thanksSaiz
S
8

Based on the Telegram Bots FAQ for sending messages, you should consider this:

If you're sending bulk notifications to multiple users, the API will not allow more than 30 messages per second or so. Consider spreading out notifications over large intervals of 8—12 hours for best results.

Shagbark answered 14/4, 2020 at 8:22 Comment(1)
Now it's even less: avoid sending more than one message per secondAerothermodynamics
O
5

I had similar problems with messages, the pause between which was 0.5 seconds (this is much less than 30 messages per second!). The problem was only associated with messages, the content of which I tried to change. So when you try to use "edit_message_text" or "edit_message_media" take more pause between messages.

Overblouse answered 1/7, 2021 at 16:3 Comment(0)
T
4

What I did with 100% degree of success was:

1- Read the returning JSON when status code is 429. That should be something like:

{
    "ok":false,
    "error_code":429,
    "description":"Too Many Requests: retry after 35",
    "parameters":{
        "retry_after":35
    }
}

2- Add a sleep based on parameters.retry_after from that JSON

3- After sleep completes, send again the last message that gave error

4- Continue to send messages on queue until you get the next 429 error

5- Repeat steps 1 and on until all messages are delivered

My code:

def postNews(news: list[str]):
    tries = 3
    for link in news:
        for i in range(tries):
            result = requests.get(f'https://api.telegram.org/botXX:YY/sendMessage', params={'chat_id': '-999999999999999', 'text': link})
            if result.status_code == 200:
                #//sleep to avoid being blocked
                time.sleep(2)
                break
            
            #//skip error sleep on last try
            if i == tries - 1:
                continue

            #//there is some error, let us do some sleep
            sleepTime = 3
            if result.status_code == 429:
                sleepTime = result.json()['parameters']['retry_after']
                
            time.sleep(sleepTime)
        else:
            #//this else gets executed if the loop don't break
            print(f'{link} - {result.status_code} {result.reason} {result.text}')
Trevatrevah answered 23/11, 2023 at 12:57 Comment(1)
Man, amazing! You've saved my botEmulation
M
0

It can happen also if a Telegram group is in the slow mode and the bot tries to send more that one message at once to that group. I fixed this by adding a delay to the bot trigger mechanism.

Menander answered 24/11, 2022 at 7:41 Comment(0)
B
0

Java version:

private Integer executeMessage(SendMessage message) {
        try {
            Message execute = execute(message);
            return execute.getMessageId();
        } catch (TelegramApiException e) {
            if (e.getMessage().contains("[429]")) {
                Pattern pattern = Pattern.compile("retry after (\\d+)");
                Matcher matcher = pattern.matcher(e.getMessage());

                if (matcher.find()) {
                    long delay = Integer.parseInt(matcher.group(1)) * 1000L;
                    try {
                        Thread.sleep(delay);
                    } catch (InterruptedException ex) {
                        ..
                    }
                }
            }
        }
        return null;
    }
Brumal answered 8/6 at 20:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.