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

3

8

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.

Transfix answered 7/11, 2017 at 20:50 Comment(1)
You can pass anything (for example update) into the context parameter when you use run_once.Tallulah
C
7

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.

Crossbeam answered 15/11, 2017 at 5:15 Comment(1)
I am getting this error: TypeError: time() missing 1 required positional argument: job_queueChristinachristine
P
5

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.

Patriciapatrician answered 1/1, 2020 at 10:25 Comment(0)
F
2

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

Fons answered 7/11, 2017 at 22:33 Comment(2)
I do store the chat_ids. The problem is that I have to catch somehow the response/confirmation from the telegram user ( update.message.text) and I can't do that without an "Update" object.Transfix
You don’t need to use cron because the library you use already has jobs. You are passing update but you can’t use update cause actually there are no updates running the function but the job parameter.Intwine

© 2022 - 2024 — McMap. All rights reserved.