error_code":403,"description":"禁止:机器人已被用户阻止。 python 中的错误句柄

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

我在 python 中使用远程机器人 API 时遇到问题。如果用户向机器人发送消息并等待响应,同时他阻止了机器人。我收到此错误,机器人不会响应其他用户:

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

试试看,catch 块没有为我处理这个错误

还有什么办法可以摆脱这种情况吗?如何发现bot被用户屏蔽并避免回复此消息?

这是我的代码:

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)

这似乎并不是一个错误,因此 try catch 将无法为您处理。您必须获取 return 代码并可能使用 if else 语句处理它(在这种情况下 switch 语句会更好,但我认为 python有它的语法)。

编辑

在方法调用 here 之后,它看起来像 reply_to() returns send_message(),其中 returns 是一个 Message 对象,其中包含json 字符串在 __init__() 方法中设置为 self.json。在该字符串中,您可能会找到状态代码(您可以根据需要捕获和处理 400s 和 500s)。

您尚未指定该机器人是在群组中还是个人。
对我来说,try and except 没有问题。

这是我的代码:

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

您可以通过多种方式处理这些类型的错误。 当然,您需要在任何您认为会引发此异常的地方使用 try/except。

所以,首先,导入异常class,即:

from telebot.apihelper import ApiTelegramException

然后,如果您查看此 class 的属性,您会看到有 error_codedescriptionresult_jsondescription 当然,当你收到错误时,Telegram 提出的是一样的。

所以你可以用这种方式重新编写你的处理程序:

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

另一种方法是使用 exception_handler,pyTelegramBotApi 中的内置函数 当您使用 tb = TeleBot(token) 初始化机器人 class 时,您还可以传递参数 exception_handler

exception_handler 必须是 class 和 handle(e: Exception) 方法。 像这样:

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")

让我知道您将使用哪种解决方案。关于第二个,老实说我从来没有用过它,但它很有趣,我会在我的下一个机器人中使用它。它应该有效!


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()`