Search code examples
pythonpython-3.xtelegrampython-telegram-botperiodic-task

How to create a cyclic thread that can be started/stopped at any time via python-telegram-bot command?


I'm writing a Telegram bot (with python-telegram-bot) that based on a command, cyclically sends messages to the user every hour.

I want to start/stop this using bot commands, adding command handlers like /start_cycle and /stop_cycle. To clarify, this is what I have in mind:

def start_cycle()
    # start in some way send_hourly_message()

def stop_cycle()
    # stop in some way send_hourly_message()

def main():
    """Entrypoint of the bot"""
    # Create updater and get dispatcher
    updater = Updater(...)
    dp = updater.dispatcher

    # Add command handlers
    dp.add_handler(CommandHandler("start_cycle", start_cycle))
    dp.add_handler(CommandHandler("stop_cycle", stop_cycle))

    # Start the bot until interrupt
    updater.start_polling(timeout=3)
    updater.idle()

The thing that puzzles me is that for how the Telegram library is conceived, there is already an event-based logic, started by updater.start_polling() and updater.idle(). I didn't find any documentation/specific information on how to make this work properly with triggerable time-based events.

What would be in your opinion the best way to do what I have in mind? I looked into asyncio a little but maybe is too complex for what I actually need?

Thanks in advance for any suggestion!


Solution

  • Thanks to @GaganTK I was able to find what i need:

    def start_notify(update, context):
        new_job = context.job_queue.run_repeating(my_callback, interval=3, first=0, name="my_job")
    
    def stop_notify(update, context):
        job = context.job_queue.get_jobs_by_name("my_job")
        job[0].schedule_removal()
    
    def my_callback(context: telegram.ext.CallbackContext):
        print(datetime.datetime.now())