How to send message in specific time TelegramBot
Asked Answered
U

3

8

Hi i want to send message from bot in specific time (without message from me), for example every Saturday morning at 8:00am. Here is my code:

import telebot
import config
from datetime import time, date, datetime

bot = telebot.TeleBot(config.bot_token)
chat_id=config.my_id    

@bot.message_handler(commands=['start', 'help'])
def print_hi(message):
    bot.send_message(message.chat.id, 'Hi!')


@bot.message_handler(func=lambda message: False) #cause there is no message
def saturday_message():
    now = datetime.now()
    if (now.date().weekday() == 5) and (now.time() == time(8,0)):
        bot.send_message(chat_id, 'Wake up!')

bot.polling(none_stop=True)

But ofc that's not working. Tried with

urlopen("https://api.telegram.org/bot" +bot_id+ "/sendMessage?chat_id=" +chat_id+ "&text="+msg)

but again no result. Have no idea what to do, help please with advice.

Ultramontanism answered 16/1, 2018 at 19:1 Comment(5)
where is the problem? is it the timing or is your bot not sending anything at all?Spake
bot does not send messageUltramontanism
does it work without your date check?Spake
nope, just dunno how to make loop here (how to periodically check the condition)Ultramontanism
I have same problem but in C# #64919290Thimbu
B
20

I had this same issue and I was able to solve it using the schedule library. I always find examples are the easiest way:

import schedule
import telebot
from threading import Thread
from time import sleep

TOKEN = "Some Token"

bot = telebot.TeleBot(TOKEN)
some_id = 12345 # This is our chat id.

def schedule_checker():
    while True:
        schedule.run_pending()
        sleep(1)

def function_to_run():
    return bot.send_message(some_id, "This is a message to send.")

if __name__ == "__main__":
    # Create the job in schedule.
    schedule.every().saturday.at("07:00").do(function_to_run)

    # Spin up a thread to run the schedule check so it doesn't block your bot.
    # This will take the function schedule_checker which will check every second
    # to see if the scheduled job needs to be ran.
    Thread(target=schedule_checker).start() 

    # And then of course, start your server.
    server.run(host="0.0.0.0", port=int(os.environ.get('PORT', 5000)))

I hope you find this useful, solved the problem for me :).

Blackness answered 26/3, 2020 at 12:36 Comment(5)
Thank you! You've been the only person who has been able to answer this question that's been asked so many times. Using threading was the key.Cheeseparing
Thankyou for the code example, I have been learning the concepts of threading lately but its hard to connect those concepts with a real world application without some example. I have a question though, you scheduled the job with scheduler and then made a thread, but you didnt call bot.polling? Why is that so. If youre not polling, why would be there a need to thread the schedule anyway?Patronage
Finally! Thanks a lot.Censorious
@shy-tan Sorry for the delayed response on this one. If you look at the line Thread(target=schedule_checker).start() you will see I create a thread object and then call its start method. This will run the schedule_checker in its own thread indefinitely. No need to use bot.polling in this case. Hope this helps!Blackness
Tried using this in VSCode. Alredy pip install the schedule package, but VSCode said the package is could not be resolve. Can you help me?Unexperienced
L
6

You could manage the task with cron/at or similar.

Make a script, maybe called alarm_telegram.py.

#!/usr/bin/env python
import telebot
import config
    
bot = telebot.TeleBot(config.bot_token)
chat_id=config.my_id
bot.send_message(chat_id, 'Wake up!')

Then program in cron like this.

00 8 * * 6 /path/to/your/script/alarm_telegram.py

Happy Coding!!!

Loathsome answered 16/1, 2018 at 19:47 Comment(2)
yeah, but thats not interesting :) Thanks for adviceUltramontanism
Not interesting ?. The awnser not resolve your problem ?Loathsome
E
1

If you want your bot to both schedule a message and also get commands from typing something inside, you need to put Thread in a specific position (took me a while to understand how I can make both polling and threading to work at the same time). By the way, I am using another library here, but it would also work nicely with schedule library.

import telebot
from apscheduler.schedulers.blocking import BlockingScheduler
from threading import Thread

def run_scheduled_task():
    print("I am running")
    bot.send_message(some_id, "This is a message to send.")
    

scheduler = BlockingScheduler(timezone="Europe/Berlin") # You need to add a timezone, otherwise it will give you a warning
scheduler.add_job(run_scheduled_task, "cron", hour=22) # Runs every day at 22:00

def schedule_checker():
    while True:
        scheduler.start()

@bot.message_handler(commands=['start', 'help'])
def print_hi(message):
    bot.send_message(message.chat.id, 'Hi!')

Thread(target=schedule_checker).start() # Notice that you refer to schedule_checker function which starts the job

bot.polling() # Also notice that you need to include polling to allow your bot to get commands from you. But it should happen AFTER threading!

Evonevonne answered 26/12, 2022 at 14:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.