Running a cron scheduler within a running thread

343 views Asked by At

I'm writing a telegram bot and I want to schedule it to send an automated message every day at a specific timing, cron style. I am using apscheduler to do it but I could not get the cron function to work. The interval scheduling works fine but it is not what I want.

I don't want to execute the .py file outside because I need the telegram bot to detect user's /start message.

So what I wanted to do was to detect user's /start message and then start the scheduler. Thereafter, the bot will send a message to the user everyday 8pm night.

Cron scheduling doesn't start and I don't know why. I suspect it is because it can't run within the main thread that I am running? Any advice would be helpful! Thank you.

import time
import telepot
import json
from telepot.loop import MessageLoop
from telepot.namedtuple import ReplyKeyboardMarkup # for custom keyboard
from telepot.delegate import pave_event_space, per_chat_id, create_open
from apscheduler.schedulers.blocking import BlockingScheduler

## Load token
TOKEN = 'TOKEN NUMBER'

# The main body
class main(telepot.helper.ChatHandler): # Implement continuous dialogue with user using DelegatorBot

    global counter1
    counter1 = 0

    global counter2
    counter2 = 0

    def __init__(self, *args, **kwargs):
        super(main, self).__init__(*args, **kwargs)

        # Initialize and create empty dictionary for storing data.
        self.indicator = '0'
        self.data = {} # initialize an empty dictionary for storing data.



    def on_chat_message(self, msg):
        content_type, chat_type, chat_id = telepot.glance(msg) # this is very important.
        # Debugging
        print(content_type, chat_type, chat_id)
        print(msg['text'])
        global counter1
        global counter2
        scheduler = BackgroundScheduler()
        #scheduler_cron = BlockingScheduler()

        # Survey function
        def survey():...
   
            return

        def repeat_message():
            bot.sendMessage(chat_id, text='type /survey to repeat survey.')
            print("Reminder sent.")

        scheduler_cron.add_job(repeat_message, 'cron', day='*', week='*', day_of_week='*', hour=20, minute=00)

     

        # Detect start messages.
        while True:
            if counter2 == 11: # If survey ends AKA 11 Qns done. Restart the counters.
                counter1 = 0
                counter2 = 0

            # once bot starts, ask user to repeat survey at a specific time of the day.

            if counter1 == 0: # If survey ends or at the very beginning of using the bot.
                # Start message.
                if msg['text'] == '/start':  # /starts initiates bot. User gets greeted with a welcome message describing what the bot will do.
                    bot.sendMessage(chat_id,
                                    text='Hello there.',
                                    parse_mode='Markdown')


                    
                    scheduler_cron.start()
                    print("Scheduler started.")

                # Start survey after initializing the bot
                elif msg['text'] == '/survey':  # /survey initiates survey.
          
                    print("Survey started...")
                    #counter1 = 0
                    counter1 += 1 

                else:
                    bot.sendMessage(chat_id, text='I do not recognise your message.')
                    msg['text'] = '' # resets msg.

            
            # User starts survey
            if counter1 == 1: # if user types /survey, counter1 +=1 and when counter1 == 1, run survey function.
                survey() # starts survey
                counter2 += 1 

      
            break



bot = telepot.DelegatorBot(TOKEN, [pave_event_space()(per_chat_id(), create_open, main, timeout=60),]) 

MessageLoop(bot).run_as_thread() # Initiates the bot on telegram. Listens for user's response. If this is stopped, the entire bot stops.
print('Listening...')
while True:
    time.sleep(1)

EDIT: I found out that apscheduler's cron does not work if I have another thread running in the background as stated in their documents:

BlockingScheduler: use when the scheduler is the only thing running in your process
BackgroundScheduler: use when you’re not using any of the frameworks below, and want the scheduler to run in the background inside your application

So it means I can't use apscheduler to make my bot work. Anyone know of any cron-like alternatives that allows me to schedule my telegram bot to fire message to users at specific timings of the day? Preferably, it has to be something that works with the telegram API.

0

There are 0 answers