Не работает цикл + обработка команд от пользователя в Telegram-боте
О проблеме: Есть задача написать Telegram-бота, который ежедневно парсит информацию с сайта и отправляет ее всем подписчикам бота. Парсер написан, бот тоже. Но я не могу реализовать совместную работу рассылки из парсера с обработкой команд в боте: /start и т.д. Либо работает только рассылка, либо работают только команды бота.
Многое пробовал методом "тыка", но в итоге везде возникала какая-нибудь другая проблема. Например, на хостинге я запускал два файла .py - один файл с рассылкой, а другой файл с самим ботом. Но тогда возникала проблема с sql - он, видимо, не может работать с 2 потоками одновременно. Если рассылка работает с sql, то файл с ботом не может обратиться к sql (например, при записи нового пользователя в базу после команды /start).
Сейчас сам предполагаю 2 решения проблемы:
- Написать всё в рамках одного файла .py: и цикл с рассылкой, и команды от пользователей. Так, наверное, sql сможет обрабатывать все запросы, если они буду идти из одного файла .py. Можно ли это сделать? Асинхронность?
- Найти базу данных, которая может работать одновременно с множеством поток. Но я не знаю, поможет ли это. Может, проблема вообще не в sql?
Ниже прикладываю код. Файлы поотдельности работают. Рассылка отправляет подписчикам, бот принимает новых подписчиков в базу. Проблема именно в совместной их работе.
Файл с ботом main.py:
from aiogram import Bot, Dispatcher, executor, types
from db import Database
bot = Bot(token='********************')
dp = Dispatcher(bot)
db = Database('database.db')
users = db.get_users()
@dp.message_handler(commands=['start'])
async def start(message: types.Message):
if message.chat.type == 'private':
if not db.user_exists(message.from_user.id):
db.add_user(message.from_user.id)
await bot.send_message(message.from_user.id, 'Подписка на ежедневные новости оформлена!')
await bot.send_message(5827479744, 'Новый подписчик!')
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)
Файл с рассылкой send_news.py(парсер был написан прямо в функции sendall - убрал его код, остались только переменные в сообщениях бота):
from db import Database
from aiogram import Bot, Dispatcher, executor, types
import asyncio
import requests
from bs4 import BeautifulSoup
from datetime import datetime
bot = Bot(token='*********************')
dp = Dispatcher(bot)
db = Database('database.db')
loop = asyncio.get_event_loop()
async def sendall():
users = db.get_users()
for row in users:
try:
begining_of_news = open('begining_of_news.png', 'rb')
with open('begining_of_news.png', 'rb') as photo:
await bot.send_photo(row[0], photo=begining_of_news)
i = 0
for el in range(len(news_for_bot)):
await bot.send_message(row[0], '◽️' + '<b>' + news_for_bot[i].strip() + '</b>' + '\n' + '\n' + gsearch_news_for_bot[i], parse_mode="HTML")
i += 1
await bot.send_message(row[0], '<i>Какой-то текст', parse_mode="HTML")
if int(row[1]) != 1:
db.set_active(row[0], 1)
except:
db.set_active(row[0], 0)
await asyncio.sleep(10)
loop.run_until_complete(sendall())