(python) Telegram bot- how to send messages periodically?

19,386

Solution 1

You need to use the context parameter when defining the job in your function. Look at this example:

   from telegram.ext import Updater, CommandHandler, MessageHandler,    Filters, InlineQueryHandler


def sayhi(bot, job):
    job.context.message.reply_text("hi")

def time(bot, update,job_queue):
    job = job_queue.run_repeating(sayhi, 5, context=update)

def main():
    updater = Updater("BOT TOKEN")
    dp = updater.dispatcher
    dp.add_handler(MessageHandler(Filters.text , time,pass_job_queue=True))


    updater.start_polling()
    updater.idle()

if __name__ == '__main__':
    main()

Now in your call back function wherever you need update. type job.context instead.

Solution 2

To send messages periodically, you can use JobQueue Extention from python-telegram-bot

Here is an example

from telegram.ext import Updater, CommandHandler

def callback_alarm(bot, job):
    bot.send_message(chat_id=job.context, text='Alarm')

def callback_timer(bot, update, job_queue):
    bot.send_message(chat_id=update.message.chat_id,
                      text='Starting!')
    job_queue.run_repeating(callback_alarm, 5, context=update.message.chat_id)

def stop_timer(bot, update, job_queue):
    bot.send_message(chat_id=update.message.chat_id,
                      text='Stoped!')
    job_queue.stop()

updater = Updater("YOUR_TOKEN")
updater.dispatcher.add_handler(CommandHandler('start', callback_timer, pass_job_queue=True))
updater.dispatcher.add_handler(CommandHandler('stop', stop_timer, pass_job_queue=True))

updater.start_polling()

the /start command will start the JobQueue and will send a message with an interval of 5 seconds, and the queue can be stopped by /stop command.

Solution 3

Try to use cron. You just need to store new chat ids somewhere (file, database ect.) and read it from your script. for example to run send_messages.py everyday at 9pm (21:00):

0 21 * * * python send_messages.py

Share:
19,386
Vasile
Author by

Vasile

Updated on June 23, 2022

Comments

  • Vasile
    Vasile almost 2 years

    I have a dilemma regarding my telegram bot. Let's say I have to create a function that will ask, every user connected to the bot, one time per week/month, a question:

    def check_the_week(bot, update):
    reply_keyboard = [['YES', 'NO']]
    bot.send_message(
        chat_id=update.message.chat_id,
        text=report,
    
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))  # sends the total nr of hours
    update.reply_text("Did you report all you working hour on freshdesk for this week?",
                      ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
    
    if update.message.text == "YES":
        update.message.reply_text(text="Are you sure?",
                                  reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
    
        # Asks confirmation
        if update.message.text == "YES":
            update.message.reply_text(text="Thank you for reporting your working hours in time!")
    
        elif update.message.text == "NO":
            update.message.reply_text(text="Please, check you time reports and add missing")
    
    elif update.message.text == "NO":
        update.message.reply_text(text="Please, check you time reports and add missing")
    

    I want this function to be triggered every week. I was thinking about using JobQueue. The problem is that in this case the function should have two parameters- bot AND job_queue, but no update:

    def callback_30(bot, job):
        bot.send_message(chat_id='@examplechannel',
        text='A single message with 30s delay')
    
    j.run_once(callback_30, 30)
    

    How can I create a Job Scheduler (or any other solution) in telegram bot to be trigger my function once a week? p.s. No "while True"+time.sleep() solutions please. The loop just stuck forever, I tried it.