How to schedule Python Telegram bot to stop at specific time and skip certain days?

I need assistance with properly scheduling my Python Telegram bot.

I have developed a bot using the python-telegram-bot library which is intended to operate from Monday to Thursday, specifically from 10 AM until 4:15 PM. On Fridays, it should be entirely inactive. Currently, the bot fails to halt at 4:15 PM as intended.

Here is the code that handles the scheduling:

import schedule
import time
from datetime import datetime
import pytz
from telegram.ext import Application, CommandHandler

# Bot configuration
TOKEN = 'your_bot_token'
source_chat = '@PriceUpdates'
dest_chat = '@MyChannel'

# Tehran timezone
tehran_tz = pytz.timezone('Asia/Tehran')

# Bot status
bot_active = False

def get_local_time():
    return datetime.now(tehran_tz)

def start_bot_operations():
    global bot_active
    bot_active = True
    print("Bot started working")

def stop_bot_operations():
    global bot_active
    bot_active = False
    print("Bot stopped working")

async def check_working_hours():
    while True:
        current = get_local_time()
        weekday = current.weekday()  # 0=Monday, 4=Friday
        hour = current.hour
        minute = current.minute
        
        # Check if it's Friday (weekday 4)
        if weekday == 4:
            if bot_active:
                stop_bot_operations()
        # Check working hours Monday-Thursday
        elif weekday < 4:
            if 10 <= hour < 16 or (hour == 16 and minute < 15):
                if not bot_active:
                    start_bot_operations()
            else:
                if bot_active:
                    stop_bot_operations()
        
        await asyncio.sleep(30)  # Check every 30 seconds

async def message_handler(update, context):
    if not bot_active:
        return
    
    # Process messages only when bot is active
    message_text = update.message.text
    processed_msg = f"Updated: {message_text}"
    await context.bot.send_message(chat_id=dest_chat, text=processed_msg)

def main():
    app = Application.builder().token(TOKEN).build()
    
    app.add_handler(CommandHandler("start", message_handler))
    
    # Start the scheduler
    asyncio.create_task(check_working_hours())
    
    app.run_polling()

if __name__ == '__main__':
    main()

The issue I’m facing is that my bot continues to run past the 4:15 PM mark. Could someone please help identify any flaws within my time checking logic? I would appreciate any assistance!

I’ve hit this timezone issue too. Your logic has a subtle bug - the condition if 10 <= hour < 16 or (hour == 16 and minute < 15) stops the bot at exactly 4:15 PM, but check_working_hours() runs every 30 seconds. So if it checks at 4:14:45 PM, it keeps running, then checks again at 4:15:15 PM and stops 15 seconds late. Drop the sleep interval to 10 seconds for tighter timing. Also, you’re creating the asyncio task wrong - asyncio.create_task() needs to be called inside an async context, but main() is synchronous. Use asyncio.get_event_loop().create_task() instead, or even better, make your main function async and use asyncio.run(main()).

You’re missing import asyncio at the top of your script. That’s why you’re getting errors when calling asyncio.sleep(30) and asyncio.create_task(). But there’s a bigger problem with your setup. You imported the schedule library but never use it, then you’re mixing asyncio tasks with polling. Running check_working_hours() as a background task while polling creates timing conflicts since run_polling() blocks everything. I’d switch to APScheduler instead. It plays much better with telegram bots and handles timezone-aware scheduling without messing with your polling. Your current approach with the global flag and checking every 30 seconds works, but it’s not great for production.

your time check is wrong. (hour == 16 and minute < 15) keeps the bot running until 4:14 pm, not stopping at 4:15. change it to (hour == 16 and minute <= 15) or just use hour < 16 if you want it stopping at 4:00 pm.