How do I schedule python telegram bot to send message at/after certain time?

2.2k views Asked by At

I'm making a telegram bot using telepot to serve as a "medical" survey. I've done up the bot and it is working. Now I want this bot to send a message automatically at certain times of the day or after 24hrs to remind the user to start the survey. Or even better, to just start the survey automatically for the user at certain timing of the day. But I'm stuck at scheduling the messages...

I'm getting about 10 messages at once for some odd reasons...

I am using apscheduler package. I did manage to automate the reminder message but because of the way telepot works, each response from the user is fed into the function causing the reminder message to appear more than once after the survey ends. I want the reminder message to appear only once a day to remind the user to start the survey. I would be happy if someone could help me fix the scheduling. Thank you in advance.

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.background import BackgroundScheduler

## Load token
TOKEN = 'klaghklsfhglka'

# The main body


class main(telepot.helper.ChatHandler): # Implement continuous dialogue with user using DelegatorBot
    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'])

        schedule = BackgroundScheduler()

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

        schedule.add_job(repeat_message, 'interval', minutes=1)
        schedule.start()  # Initiates the scheduler to send automated message.

        # Survey function
        def survey():

    # Symptoms

            if self.indicator == 'choose_symptom':
                # show custom keyboard
                mark_up = ReplyKeyboardMarkup(keyboard=[['Pain'], ['Trouble with Breathing'], ['Tiredness'], ['Appetite'], ['Feeling sick'], ['Vomitting'], ['Bowel upset'], ['Hair loss']], one_time_keyboard=True)
                # keyboard options are defined in the form of arrays. Text of each array element will appear on keyboard.
                bot.sendMessage(chat_id, text='Was there any discomfort today?', reply_markup=mark_up)  # Ask user question
                self.indicator = 'rate_symptom' # move to next question

            elif self.indicator == 'rate_symptom':
                self.data['symptoms'] = msg['text'] # after moving to next section, this line of code stores the previous reply to the self.data dictionary.
                mark_up = ReplyKeyboardMarkup(keyboard=[['Not at all'],['A little'],['Somewhat'],['Very much']], one_time_keyboard=True)
                bot.sendMessage(chat_id, text='Please rate the feeling.', reply_markup=mark_up)
                self.indicator = 'set_data' # move to next section



    # Set data
    # Store data in json file. This chunk of code should be at the end of everything.

            elif self.indicator == 'set_data':
                self.data['symptoms_score'] = msg['text']
                self.data['date'] = time.ctime(msg['date']) # convert the time from long to normal format
                with open('data.json', 'a') as handle: # stores all input into a .json file.
                    json.dump(self.data, handle)
                    handle.write("\n")
                    handle.close()
                bot.sendMessage(chat_id, text='Thank you for feedback.')
         

            return


        # Detect start messages.
        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.',
                            parse_mode='Markdown')

        elif msg['text'] == '/survey':  # /survey initiates survey.
            self.indicator = 'choose_symptom'
            print("Survey started...")

        survey() #starts survey


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

MessageLoop(bot).run_as_thread() 
print('Listening...')
while 1:
    time.sleep(10)
2

There are 2 answers

0
Cropo On

You could look at using Task Scheduler in Windows to run the py file via cmd.

0
Nicopii On

Turns out I have to use a lot of counters to split the user input into different baskets... if that makes sense?