I have a Telegram bot written in Python using the Telethon library. The bot is supposed to function from 10:00 to 16:15 from Saturday to Thursday, and it should be completely inactive on Fridays. However, I’m having trouble getting the bot to stop exactly at 16:15. The bot currently doesn’t stop correctly at the specified time.
Here’s the relevant part of my code:
import logging
import re
import random
import jdatetime
from telethon import TelegramClient, events
from datetime import datetime, timedelta
import asyncio
import pytz
# API information
api_id =
api_hash = ''
phone_number = ''
channel_id = '@DolarRates'
group_usernames = ['@gheymateTehran2', '@DOLARRATE1', '@gheymateTehran'] # Group usernames
# New channel information
new_channel_id = 'https://t.me/Akhbargeymat'
target_channel_id = '@DolarRates'
# Logging settings
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Proxy settings (if needed)
proxy = None # ('socks5', '127.0.0.1', 9050) # Example for SOCKS5 proxy
# Create a Telegram client with proxy settings
client = TelegramClient('session_name', api_id, api_hash, proxy=proxy)
# Lock for managing message sending
send_lock = asyncio.Lock()
# Variable for storing the time of the last sent message
last_sent_time = datetime(1970, 1, 1, tzinfo=pytz.UTC)
# Global variable to store the new dollar rate
global_new_number_str = "نامشخص" # Initial value
# Variable for bot running status
is_running = False
# Function to get Tehran time
def tehran_time():
tehran_tz = pytz.timezone('Asia/Tehran')
return datetime.now(tehran_tz)
async def send_message_to_channel(message):
try:
logger.info(f"Sending message to channel: {message}")
await client.send_message(channel_id, message)
except Exception as e:
logger.error(f"Failed to send message: {e}")
def get_persian_date():
today = jdatetime.date.today()
return today.strftime('%Y/%m/%d')
async def process_message_text(text):
global last_sent_time, global_new_number_str
current_time = tehran_time()
async with send_lock:
if (current_time - last_sent_time).total_seconds() < 60:
logger.info("Skipping message send due to time limit.")
return None
# Find the first 5-digit number in the text
match = re.search(r'bd{2},d{3}b', text)
if match:
# Extract the number
original_number = match.group()
# Remove the comma and convert to an integer
number = int(original_number.replace(',', ''))
# Decrease the number by 50
new_number = number - 50
# Format the new number as a string with commas
new_number_str = f'{new_number:,}'
# Store the new number in the global variable
global_new_number_str = new_number_str
# Create the output message
processed_text = f"""
✨ #نرخ_دلار
📆 تاریخ: {get_persian_date()}
💸 #دلار سبزه : {new_number_str} تومان
🌟 بروزترین قیمتها رو همین حالا مشاهده کنید.
📲 کانال قیمت #دلار تهران 👇
🆔@DolarRates
"""
last_sent_time = current_time
return processed_text.strip()
else:
logger.error("No 5-digit number found in the text.")
return None
# Function to process messages from the new channel
def process_new_channel_message(text):
# Remove unwanted parts
text = re.sub(r'🔸دلار آمريکا.*?\n', '', text)
text = re.sub(r'⏰ساعت.*?\n', '', text)
text = re.sub(r'✅ @Akhbargeymat', '', text)
text = re.sub(r'✅ .*?\n', '', text)
text = text.replace('🔸', '')
text = text.replace('✅', '') # Remove ✅
text = text.replace('****', '') # Remove ****
# Replace flags
text = text.replace('يورو', '🇪🇺 يورو')
text = text.replace('پوند انگليس', '🇬🇧 پوند انگليس')
text = text.replace('درهم امارات', '🇦🇪 درهم امارات')
text = text.replace('يوآن چين', '🇨🇳 يوآن چين')
text = text.replace('لير ترکيه', '🇹🇷 لير ترکيه')
text = text.replace('دینار کویت', '🇰🇼 دینار کویت')
text = text.replace('🔹', '🟡')
text = text.replace('@Akhbargeymat', '')
# Align text to the right
lines = text.split('n')
aligned_text = 'n'.join(line.strip() for line in lines if line.strip())
# Add new text
additional_text = """
🌟 بروزترین قیمتها رو همین حالا مشاهده کنید.
📲 کانال قیمت #دلار تهران 👇
🆔@DolarRates
"""
return aligned_text.strip() + '\n\n' + additional_text.strip()
# Function to read the latest posts from groups and send the newest message every minute
async def read_latest_posts():
while is_running:
for group_username in group_usernames:
try:
logger.info(f"Reading latest post from {group_username}")
messages = await client.get_messages(group_username, limit=1)
if messages:
latest_message = messages[0]
processed_text = await process_message_text(latest_message.text)
if processed_text:
logger.info(f"Latest post fetched from {group_username}: {processed_text}")
await send_message_to_channel(processed_text)
except Exception as e:
logger.error(f"Failed to read latest post from {group_username}: {e}")
await asyncio.sleep(60) # Wait one minute
# Function to read and forward messages from the new channel every 40 minutes without time limits
async def read_and_forward_from_new_channel():
while is_running:
try:
logger.info(f"Reading latest post from {new_channel_id}")
messages = await client.get_messages(new_channel_id, limit=1)
if messages:
latest_message = messages[0]
processed_text = process_new_channel_message(latest_message.text)
if processed_text:
logger.info(f"Latest post fetched from {new_channel_id}: {processed_text}")
await send_message_to_channel(processed_text)
await asyncio.sleep(2400) # Wait 40 minutes
except Exception as e:
logger.error(f"Failed to read and forward from new channel: {e}")
# Handler for new messages
@client.on(events.NewMessage(chats=group_usernames))
async def handler(event):
if is_running:
try:
processed_text = await process_message_text(event.message.text)
if processed_text:
logger.info(f"New message received from {event.chat.username}: {processed_text}")
await send_message_to_channel(processed_text)
except Exception as e:
logger.error(f"Failed to handle new message from {event.chat.username}: {e}")
# Send greeting and farewell messages
async def send_greeting_messages():
while is_running:
now = tehran_time()
if now.hour == 10 and now.minute == 0:
await send_message_to_channel("به نام خدا")
elif now.hour == 19 and now.minute == 0:
await send_message_to_channel("به امید دیدار")
await asyncio.sleep(60) # Check every minute
# Send automatic messages every 5 to 8 minutes
async def automated_posting():
while is_running:
tehran_current_time = tehran_time().strftime('%H:%M:%S')
special_message = f"""
✨ #نرخ_دلار
📆 تاریخ: {get_persian_date()}
مـعامله انجام شد✅
💸 #دلار سبزه : {global_new_number_str} تومان
🌟 بروزترین قیمتها رو همین حالا مشاهده کنید.
📲 کانال قیمت #دلار تهران 👇
🆔@DolarRates
"""
await send_message_to_channel(special_message.strip())
await asyncio.sleep(random.randint(300, 480)) # Wait between 5 to 8 minutes
# `Function to stop the bot's activities`
`async def shutdown_bot():`
`global is_running`
`is_running = False`
`logger.info("Bot activities have been stopped.")`
`async def main():`
`global is_running`
`logger.info("Starting client...")`
`try:`
`await client.start(phone_number)`
`except Exception as e:`
`logger.error(f"Failed to start client: {e}")`
`else:`
`logger.info("Client started.")`
`while True:`
`now = tehran_time`()
# Check the time and day to start and stop the bot
if now.weekday() != 4 and (10 <= now.hour < 16 or (now.hour == 16 and now.minute < 15)):
if not is_running:
is_running = True
logger.info("Bot is starting its activities.")
await asyncio.gather(
send_greeting_messages(),
automated_posting(),
read_and_forward_from_new_channel(),
read_latest_posts()
)
else:
if is_running:
await shutdown_bot()
logger.info("Bot is out of working hours or it's Friday.")
await asyncio.sleep(60) # Check every minute to start activities
`if `__`name`__` == "`__`main`__`":`
`logger.info("Running main...")`
`client.loop.run_until_complete(main())`
`client.run_until_disconnected()`
I have tried to make the bot work from 10:00 to 16:15 from Saturday to Thursday and stop exactly at 16:15. However, it doesn't stop as expected. Could anyone help me identify what I'm doing wrong?
Thank you in advance for your help!
Dragan Marković is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.