skip to Main Content

I’m trying to apply decorator from another class on method in my class…
it is my implementation of this Telegram API wrapper library:
https://github.com/eternnoir/pyTelegramBotAPI

But in my example want to use it not from script – but as method of class like that:

class Bot:

    def __init__(self, key):
        self.key = key
        self.bot=telebot.TeleBot(key)

    def start(self):
        self.bot.polling()

    # Handle '/start' and '/help'
    @self.bot.message_handler(commands=['help', 'start'])
    def send_welcome(self,message):
        self.bot.reply_to(message, """
        Hi there, I am EchoBot. 
        I am here to echo your kind words back to you. 
        Just say anything nice and I'll say the exact same thing to you!
        """)


    # Handle all other messages with content_type 'text' (content_types defaults to ['text'])
    @self.bot.message_handler(func=lambda message: True)
    def echo_message(message):
        self.bot.reply_to(message, message.text)

All self are highlighted … and certainly not working – will be glad if someone can explain what im doing wrong?
The original example trying to customize is:

import telebot

bot = telebot.TeleBot("TOKEN")

@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
    bot.reply_to(message, "Howdy, how are you doing?")

@bot.message_handler(func=lambda message: True)
def echo_all(message):
    bot.reply_to(message, message.text)

bot.polling()

5

Answers


  1. Chosen as BEST ANSWER

    for those who might need it - solution i found - was to put the functions inside Ctor - and not to apply decorators to class methods .... :

    class Bot:
    
    def __init__(self, key,greting):
        self.key = key
        self.bot=telebot.TeleBot(key)
        self.greting=greting
    
        # Handle '/start' and '/help'
        @self.bot.message_handler(commands=['help', 'start'])
        def send_welcome(self, message):
            self.bot.reply_to(message,self.greting )
    
        # Handle all other messages with content_type 'text' (content_types defaults to ['text'])
        @self.bot.message_handler(func=lambda message: True)
        def echo_message(message):
            self.bot.reply_to(message, message.text)
    
    def start(self):
        x = threading.Thread(name=self.greting, target=self.bot.polling,)
        x.start()
    

  2. self though a keyword is more of a placeholder variable name for the 1st argument for all methods that is always the instance object (except for classmethod where 1st argument is the class itself and staticmethod where there is neither)

    For any method, even if you use this instead if self as 1st argument of any method, you can access all the object attributes as this.foo or methods as this.bar().

    So technically, you don’t have access to the object outside any method. The decorator is at the outer most level where you cannot access object (which is passed only to methods as the 1st argument)

    A complex and unnecessary workaround I can think of is to write a static method that will help you catch the self object from argument and then access it’s message_handler

    Login or Signup to reply.
  3. I think that proper method is to use lambda functions. You can pass more than one parameter to it and get self from outer scope.

    So, i finished with next sample

    import telebot
    
    
    class Telegram:
        def __init__(self, token):
            self.channel = telebot.TeleBot(token, parse_mode=None)
    
            start_dict = dict(
                function=lambda msg, obj=self: obj.start_handler(msg),
                filters=dict(
                    commands=["start"],
                )
            )
            self.channel.add_message_handler(start_dict)
    
            self.channel.polling()
    
        def start_handler(self, message):
            print("START command")
    
    
    test = Telegram("your-token-here")
    

    You can run it from console and it will print START command every time you send /start to it.

    Login or Signup to reply.
  4. You should set object of TeleBot() in method start().

    import telebot
    from decouple import config as key
    
    class TelegramBot():
        def bot(self):
            bot = telebot.TeleBot(key('token'))
    
            @bot.message_handler(commands=['start'])
            def start(message):
                bot.send_message(message.chat.id, "Sup, Sani :)")
            
            bot.polling(none_stop=True)
    
    TelegramBotSpot().bot()
    
    Login or Signup to reply.
  5. class Variaveis:
        
        def __init__(self):
            self.bot = telebot.TeleBot(token='')
    
            @self.bot.message_handler(commands=["start"])
            def _process_command_start(message):
                self.process_command_start(message)
    
            self.bot.polling(none_stop=True, timeout=123)
    
        #----------------------------------------------------------------------------------------------------------------#
        # Começando a programar :
        
        def process_command_start(self, message):
            self.bot.send_message(message.chat.id, 'ola mundo')
    
    
    Variaveis()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search