error_code":403,"description":"Forbidden: bot was blocked by the user. error handle in python
Asked Answered
K

4

9

I have a problem using telebot API in python. If the user sends a message to the bot and waits for the response and at the same time he blocks the bot. I get this error and the bot will not respond for other users:

403,"description":"Forbidden: bot was blocked by the user

Try, catch block is not handling this error for me

any other idea to get rid of this situation? how to find out that the bot is blocked by the user and avoid replying to this message?

this is my code:

import telebot
import time


@tb.message_handler(func=lambda m: True)
def echo_all(message):
    try:
           time.sleep(20) # to make delay 
           ret_msg=tb.reply_to(message, "response message") 
           print(ret_msg)
           assert ret_msg.content_type == 'text'
    except TelegramResponseException  as e:
            print(e) # do not handle error #403
    except Exception as e:
            print(e) # do not handle error #403
    except AssertionError:
            print( "!!!!!!! user has been blocked !!!!!!!" ) # do not handle error #403
     

tb.polling(none_stop=True, timeout=123)
Kayekayla answered 24/8, 2021 at 18:43 Comment(3)
I filed an edit to remove the python-telegram-bot tag, which is the tag for a different library. please tag the library that you're actually using ;)Robinson
@Robinson There is no telebot tag in Stackoverflow! the python-telegram-bot was the best choice !Kayekayla
there is a tag called py-telegram-bot-api, which is the name of the library that provides the telebot module pypi.org/project/pyTelegramBotAPI. the python-telegram-bot is not a generic tag for telegram bots written in python but exclusively for the python library with the same name ;)Robinson
R
4

You can handle these types of error in a lot of way. For sure you need to use try/except everywhere you think this exception would be raised.

So, first, import the exception class, that is:

from telebot.apihelper import ApiTelegramException

Then, if you look at attributes of this class, you will see that has error_code, description and result_json. The description is, of course, the same raised by Telegram when you get the error.

So you can revrite your handler in this way:

@tb.message_handler() # "func=lambda m: True" isn't needed
def echo_all(message):
    time.sleep(20) # to make delay
    try:
           ret_msg=tb.reply_to(message, "response message")
    except ApiTelegramException as e:
           if e.description == "Forbidden: bot was blocked by the user":
                   print("Attention please! The user {} has blocked the bot. I can't send anything to them".format(message.chat.id))

Another way could be to use an exception_handler, a built-in function in pyTelegramBotApi When you initialize your bot class with tb = TeleBot(token) you can also pass the parameter exception_handler

exception_handler must be a class with handle(e: Exception) method. Something like this:

class Exception_Handler:
    def handle(self, e: Exception):
        # Here you can write anything you want for every type of exceptions
        if isinstance(e, ApiTelegramException):
            if e.description == "Forbidden: bot was blocked by the user":
                # whatever you want

tg = TeleBot(token, exception_handler = Exception_Handler())
@tb.message_handler()
def echo_all(message):
    time.sleep(20) # to make delay
    ret_msg = tb.reply_to(message, "response message")

Let me know which solution will you use. About the second, I've never used it honestly, but it's pretty interesting and I'll use it in my next bot. It should work!

Roseroseann answered 14/12, 2021 at 7:57 Comment(0)
T
3

This doesn't appear to actually be an error and thus try catch won't be able to handle it for you. You'll have to get the return code and handle it with if else statements probably (switch statements would work better in this case, but I don't think python has the syntax for it).

EDIT

Following the method calls here it looks like reply_to() returns send_message(), which returns a Message object, which contains a json string set to self.json in the __init__() method. In that string you can likely find the status code (400s and 500s you can catch and deal with as you need).

Trotyl answered 27/8, 2021 at 7:58 Comment(4)
can you write an example?Kayekayla
Might be able to, if you can print out the result of ``` response = tb.reply_to(message, "response message") print(response.json) ``` I'm not familiar with telebot, so that might not even be possible, but from the code I saw on the repo, you should be able to get a string with the http status response code from that. If you can, post it here, please.Trotyl
It is possible to get the JSON response, but in case of error, there is no JSON to return!. I managed to raise an error using assert in python but if I send a message and I delete the bot before receiving the response, the assert is never raised because there is no return JSON.Kayekayla
If there is no JSON and this is an error, the try-catch block will do as you wish. We still need to know what ret_msg.json prints out. If it's a string, you'll have to manually parse the status code out. Otherwise, there should be a key called something like status that you can call to get the value of the http status code and then deal with it with your if-else statements.Trotyl
E
1

You haven't specified whether the bot is in a group or for individuals.
For me there were no problems with try and except.

This is my code:

@tb.message_handler(func=lambda message: True)
def echo_message(message):

    try:
        tb.reply_to(message, message.text)
    except Exception as e:
        print(e)

tb.polling(none_stop=True, timeout=123)
Everyday answered 27/8, 2021 at 18:3 Comment(8)
it's for individuals, but if there is a queue for lots of responses and the sender to your bot blocks your bot before getting the response . you also get error 403 and your bot will not response anymoreKayekayla
@Kayekayla I tried with my code and 2 phone and it worksEveryday
try to use send a photo with delay in your bot and block your message before the bot sends you a message, you will get the error .Kayekayla
@Kayekayla In your example you used some text not a photo ... I tested the text and it works ... The error is caught and the other gets the answer. Have you tried with my code?Everyday
I did try your code, it's the same. use time.sleep(20) before reply_to function and send a few requests to the bot and delete the bot. you will get the same error as me. try-catch is not working for error #403Kayekayla
@Kayekayla Can you send a video? because I have tried and it works correctly ... You know that you have to wait 20 seconds for the second user too since you use the time.sleep ()?Everyday
I have to do some process to reply the user , it takes 3 to 5 second per request but whoever send a request to bot will have to wait in a queue. That's why i added sleep (20) , cus the server side sleep for 20 sec but user side keep sending the request. and you have time time to delete the bot before you get the response and test the error 403Kayekayla
@Kayekayla If you still can't try with bt.stop_pollling() and after that you can use a bt.pollling() in a function... with this you should solve.Everyday
M
0

def command_start(update: Update, context: CallbackContext):
  bot = context.bot
  cid = update.message.chat_id
  bot.send_message(cid, "Bot para aprender")

def repeat_test(context: CallbackContext): 
  usuarios = ['1732411248','1284725300']
  job = context.job
  for usuario in usuarios:
   context.bot.send_message(chat_id=usuario, text=job.context)
        
def bot_main():
  updater = Updater(BOT_TOKEN, use_context=True)
  dp = updater.dispatcher
  dp.add_handler(CommandHandler("start", command_start))

  job_que = updater.job_queue

  morning = datetime.time(2, 21, 1, 1, tzinfo=pytz.timezone("Cuba"))
  
  job_que.run_daily(repeat_test, morning25, context="sense")
  job_que.start()   

  updater.start_polling(timeout=30) 
  updater.idle()` 
Malmo answered 10/1, 2022 at 1:46 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Felloe

© 2022 - 2024 — McMap. All rights reserved.